Как сделать фильтр на сайте django

Обновлено: 04.07.2024

Я использую Джанго-фильтр , который работает большой , но у меня возникли проблемы фильтрации мой раскрывающийся список выбора (который основан на модели) текущей импорт django_filters из Джанго импорта форм из . модели импорта проекта , задачи из django_currentuser . импорт промежуточного ПО get_current_user , get_current_authenticated_user класс MasterListFilter ( django_filters . FilterSet ): project = django_filters . ModelChoiceFilter ( метка = 'Проекты' , имя = 'project_fkey' , QuerySet = Project . Объекты . Отфильтровываются ( deleted__isnull = Правда , user_fkey = 3 ). Отчетливый ( 'код' ) ) класс Meta : модель = Задание полей = [ 'проект' ] @property def qs ( self ): parent = super ( MasterListFilter , self ). qs user = get_current_user () возвращает родительский элемент . filter ( master = True , deleted__isnull = True , user_fkey = user . id ) . Это довольно простой и распространенный сценарий, когда у вас есть дочерняя таблица, которая имеет отношение много к одному к родительской таблице. Я хочу отфильтровать таблицу дочерних записей, выбрав родителя. Все это довольно просто, стандартно. Муха в мазке - это когда родительские записи создаются разными пользователями, и вы хотите показать родительские записи в выпадающем списке, принадлежащем текущему пользователю.

Вот мой код от filters.py

Этот бит отлично работает:

Это фильтрует мой основной список, так что отображаются только те записи, у которых установлен главный флаг, не были удалены и принадлежат к текущему пользователю. Это именно то, чего я хочу.

Этот следующий бит также работает и дает мне отфильтрованный выпадающий список, который я ищу, потому что у меня есть hardcoded 3 как user.id

Очевидно, я не хочу иметь hardcoded id. Мне нужно получить значение текущего пользователя. Следуя той же логике, используемой для фильтрации основной таблицы, я в конечном итоге получаю это.

Итак, как я могу надежно получить текущего пользователя в свой файл filter.py, чтобы я мог использовать его для фильтрации моего списка вниз.

Спасибо заранее и счастливое кодирование.

EDIT: Итак, после предложения Wiesion я изменил свой код, как было предложено, но я все еще получаю запрос if : None : Type Error, говорящий, что у пользователя нет идентификатора атрибута. Похоже, я не получаю текущего пользователя. Поэтому, возвращаясь к документам и пытаясь объединить их предложение с Wiesion (чье объяснение дает общий смысл - спасибо Wiesion), я придумал следующее:

Подобные работы в теории, но ничего не дают в выпадающем списке, потому что

Как мы уже упоминали в предыдущей части – в систему шаблонов включены теги и шаблоны. В этой части мы кратко рассмотрим наиболее используемые из них.

Теги (tags)

if/else

Тег проверяет значение переменной, и если оно True (т.е. – она не пустая, и её булево значение не false ) – система отобразит всё, что указано между и , например:

Тег не обязателен:

Проверка значений в Python

В Python и в системе шаблонов Django следующие объекты будут иметь значение False :

  • пустой список ( [] );
  • пустой кортеж ( () );
  • пустой словарь ( <> );
  • пустая строка ( '' );
  • ноль ( 0 );
  • специальный объект None;
  • объект False (это очевидно);
  • другие объекты, которые имеют собственное логическое поведение;

Всё остальное будет иметь значение True

Тег может принимать операторы and , or или not для проверки нескольких переменных. Например:

С тегом нельзя одновременно использовать операторы and и or , так как это сделает результат двусмысленным. Следующий пример будет некорректным:

Использование скобок для контроля над порядком операций недопустимо. Если вы всё же решили, что вам необходимо использование скобок – выполните логическую выборку вне шаблона, и передайте результат как отдельную переменную. Либо – используйте вложенный тег , например так:

Множественное использование одного и того же логического оператора допустимо, но нельзя комбинировать различные операторы в одном теге. Например, следующий код будет работать верно:

В Django нет тега , но вы можете использовать вложенные теги для реализации задачи:

Убедитесь, что все теги закрыты . Иначе – Django вызовет исключение TemplateSyntaxError .

Тег позволяет вам выполнять итерацию элементов в последовательности. Как и оператор for в Python, синтаксис его выглядит как for X in Y , где Y – это последовательность элементов, а X – имя переменной для использования в каждом цикле. Каждый раз при выполнении цикла – система шаблонов будет выполнять рендеринг всего, что заключено между и .

Например, вы можете использовать такой код для отображения списка спортсменов, заданных в списке athlete_list :

Вы может добавить reversed , что бы выполнить итерацию в обратном порядке:

Допустимо использование вложенных циклов :

Так как такая проверка используется очень часто, поэтому тег for поддерживает оператор , который позволяет определить – что отображать, если список пустой. Следующий пример будет работать так же, как и предыдущий

В тегах Django нет аналога оператора break для выхода из цикла до его завершения. Если вы хотите выполнить подобное действие – измените саму переменную, участвующую в цикле так, что бы в ней были только те данные, которые должны быть в цикле (примечание: тут>>> есть примеры того, что имеется ввиду в этом параграфе). Аналогично – нет поддержки оператора continue , который должен возвращать выполнение цикла к его началу (смотрите следующий раздел “Философия и Ограничения” далее в этой главе).

Внутри каждого цикла у вас есть доступ к переменной шаблона forloop . Она содержит несколько атрибутов, которые могу предоставить вам информацию о процессе выполнения цикла:

forloop.counter содержит в себе количество выполненных итераций цикла. Его индекс начинается с 1, а не с 0, и при первом выполнении цикла forloop.counter будет равен 1. Например:

forloop.counter0 аналогичен с forloop.counter , но его отсчёт начинается с нуля, а не единицы.

forloop.revcounter содержит в себе количество оставшихся итераций. При первом выполнении цикла этот счётчик будет содержать в себе общее количество элементов в заданной циклу последовательности. При выполнении последней итерации – он будет равен 1.

forloop.revcounter0 аналогичен forloop.revcounter , с той разницей, что он заканчивается на 0, а не 1. При первом выполнении цикла – его значение будет равно общему количеству элементов -1, а при последнем – нулю.

forloop.first – логическое (булево) значение, содержит True при первом выполнении цикла. Удобен для особых случаев, например:

forloop.last – аналогичен forloop.first , но будет True при последнем выполнении цикла. Часто используется для добавления | между элементами списка ссылок:

Результат будет выглядеть так:

Другой пример использования – добавление запятой между словами в списке:

forloop.parentloop – ссылка на родительский цикл в случаях с вложенными циклами, например:

Специальная переменная forloop допустима только в циклах. Как только парсер шаблона достигнет – переменная forloop исчезнет.

Context и переменная forloop

Внутри блока существующие переменные “сдвигаются”, что бы избежать перезаписи значения специальной переменной forloop . Как правило, вам не стоит переживать на этот счёт, но если вы используете свою переменную forloop (хотя это не рекомендуется), она будет названа forloop.parentloop внутри всего блока .

ifequal/ifnotequal

Система шаблонов Django разработана не как язык программирования, и в ней недопустимо использование обычных операторов Python. Однако, очень часто требуется сравнить две переменные и отобразить что-либо, если они не идентичны – для этого в Django используется тег .

Тег сравнивает два значения, и отображает всё, что задано между и если значения одинаковы.

В этом примере сравниваются две переменные шаблона – user и currentuser :

Аргументами можно использовать непосредственно строку, заключённую в одинарные или двойные кавычки:

Как и в теге , в можно использовать :

В качестве аргументов можно использовать только переменные, строки, целые и десятичные числа:

Любые другие типы переменных, такие как словари, списки и логические типы – недопустимы. Вот неправильные примеры использования :

Если вам необходимо проверить что-либо истинно или ложно – используйте тег вместо .

Комментарии

Как и в HTML или Python, система шаблонов Django поддерживает добавление комментариев в код. Что бы обозначить его – используйте тег :

Этот комментарий не будет отображён при рендеринге шаблона.

Комментарии с использованием могут быть только однострочными – такое ограничение ускоряет парсинг шаблона.

Если вы хотите использовать многострочный комментарий – используйте тег , например:

Фильтры

Как уже было сказано в этой главе ранее, фильтры шаблона являются самым простым и удобным способом изменить значение переменной перед её отображением. Фильтры используют символ pipe | , например так:

Таким образом будет выведено значение переменной > после применения фильтра lower , который переведёт текст в нижний регистр символов.

Фильтры могут быть объединены в цепочки и использованы вместе, таким образом вывод одного фильтра будет передан на обработку второму фильтру. В следующем примере первый элемент списка попадает под фильтр, а потом изменяется в заглавные символы:

Некоторые фильтры могут принимать аргументы. Аргументы фильтра указываются после двоеточия и в двойных кавычках:

Так будут выведены первые 30 символов переменной bio .

Вот несколько наиболее полезных фильтров:

addslashes – добавляет символы косой черты перед любыми другими слешами, одинарными или двойными кавычками. Полезно при использовании JavaScript в коде.

date – форматирование объектов date или datetime в соответствии с заданными параметрами, например:

length – возвращает длину значения переменной. Для списка – количество элементов, для строки – количество символов. Работает с любым объектом, который поддерживает метод __len__() .

Таким образом, в основном у меня есть сайт в Django, который является витриной, и у конечного пользователя есть три фильтра. Фильтр типа продукта (брюки, обувь, рубашки и т.д.), Фильтр доставки (да/нет) и фильтр местоположения/популярности.

В настоящее время на моем view.py у меня есть этот метод.

Как вы можете видеть, это обрабатывает первый фильтр. Проблема, с которой я столкнулась, – это выбрать, скажем, “штаны”, он фильтрует штаны, но игнорирует то, что было выбрано в двух других фильтрах. Другой пример, допустим, я выбираю штаны, страница заполняется результатами этого фильтра. Но если я затем перейду к фильтру доставки и выберите “Да”, страница будет заполнена предметами, которые будут доступны только, но фильтр “брюки” забыт.

Я пытаюсь понять, как создать набор запросов в моих представлениях, который запоминает два других запроса (если это имеет смысл).

Единственный способ, которым я могу это сделать, – создать флаги True/False для каждого значения в каждом из фильтров, а затем добавить, вероятно, 100 строк операторов if/then, проверяющих каждый флаг. Должен быть лучший способ.

Вот как я передаю значение фильтра из моего шаблона.

В my views.py это не сработает:

Потому что мне нужно будет фильтровать по видам (“брюки”, “рубашки”, обувь) и “доставка” (“доставка”, “доставка”). У каждого фильтра есть свой столбец в моей модели.

Вы можете пройти через запятую список filter значений:

И затем получите записи, используя поиск __in :

Или используйте метод getlist() для QueryDict :

С тем же вызовом ORM:

UPDATE: Чтобы передать несколько типов в представление, сохраните их в массиве и используйте метод join() чтобы получить строку с разделителями-запятыми:

ОБНОВЛЕНИЕ 2: Если вы используете два поля для фильтрации запроса, тогда вам нужно создать два отдельных списка:

Цель лекции: Рассмотреть принцип создания пользовательских шаблонов тегов и фильтров, ознакомиться с общими представлениями на основе классов, ознакомиться с вложенными подфреймворками и их основными параметрами.

Пользовательские шаблоны тегов и фильтры

Система шаблонов Django поставляется с множеством шаблонов тегов и фильтрами, которые делают написание шаблонов легкой и гибкой работой. Иногда, вы, возможно, захотите расширить систему шаблонов собственными тегами и фильтрами. Это обычно происходит, когда вы находите повторяющуюся структуру одного и того же тега множество раз, когда вы хотите обернуть структуру в единый тег , или даже тогда, когда у вас есть фильтр, который вы хотите добавить в систему шаблонов.

Угадайте, что? Django уже позволяет вам сделать это, и это довольно легко! Вы в основном добавите новый пакет к вашему приложению, назовете его templatetags и положите модули, которые содержат теги и фильтры в него. Давайте узнаем об этом, добавив фильтр, который использует строку. Добавим каталог templatetags в родительский каталог mytweets и положим пустой файл под названием_ init_.py туда, так чтобы Python рассматривал каталог как пакет. Теперь создайте модуль под названием mytweet_filters в нем. Мы собираемся написать наш фильтр в этом модуле Вот пример структуры каталога:

Теперь добавьте следующий код к файлу mytweet_filters.py:

Переменная register является объектом, который может использоваться для введения новых тегов и фильтров в систему шаблонов. Здесь мы использовали декоратор register .filter для добавления функции смены прописных букв в качестве фильтра.

Чтобы использовать новый фильтр из внутри шаблона, добавьте следующую строку в начало вашего файла шаблона:

Затем можно использовать новый фильтр так же, как любой другой фильтр, предлагаемый Django:

Добавление пользовательского шаблона тегов работает аналогично с фильтрами. В основном, вы определяете методы для обработки тегов и затем регистрируете тег , чтобы сделать его доступным для шаблонов. Этот процесс немного сложнее, потому что теги могут быть более сложными, чем фильтры. Дополнительную информацию о пользовательских шаблонах тегов доступны в документации по Django

При написании пользовательского фильтра, вы должны заботиться о поведении авто-исключения Django с фильтром. Существует три типа строк, которые могут быть переданы в фильтр:

  • Raw String : строка подготовленная либо командой str или сформированная из символов Unicode. Они автоматически исключаются, если включено автоматическое исключение.
  • Safe strings: эти строки являются строками, которые помечены от дальнейшего исключения. Они не нуждаются в каких-либо дальнейших исключениях. Чтобы пометить вывод как безопаснцю строку, используйте модуль django.utils.safestring.mark_safe().
  • Строки помеченные как "нуждающиеся в исключении": как и предполагает название, их всегда нужно избегать

Общие представления на основе классов

Во время работы с Django, вы заметите, что существуют определенные типы представлений, которые всегда необходимы независимо от проекта, над которым вы работаете. По этой причине Django поставляется с набором представлений, которые можно использовать в любом проекте. Эти представления называются общие представления.

Django предоставляет общие представления для следующих целей:

  • Для создания простых представлений для таких задач, как перенаправление на другой URL-адрес или отображение шаблона.
  • Просмотр и формирование представлений для отображения объектов из модели данных – эти представления аналогичны тому, как страница администратора отображает списки и страницы сведений для данных моделей
  • Для создания страниц на основе даты архива; Это может быть особенно полезно для блогов
  • Для создания, редактирования и удаления объектов в модели данных

Представления Django на основе классов можно настроить путем определения подклассов, или путем передачи аргументов непосредственно в URL- адрес conf.

Подклассы полны соглашений, которые устраняют хлопоты, связанные, чтобы переписать шаблоны в самых распространенных ситуациях. Когда вы используете подкласс можно переопределить атрибут или методы основного класса, подставив новое значение :

Мы также добавим эту запись в файл urls.py, чтобы получить перенаправление:

Интересно, что мы можем достичь того же самого, изменив файл и добавив несколько строк в файл urls.py:

Вложенные подфреймворки

Пакет Django.contrib содержит стандартную библиотеку Django. Мы использовали следующие подфреймворки из этого пакета в предыдущих главах этой книги:

  • admin: это интерфейс администратора Django
  • auth: это система аутентификации пользователей
  • sessions: это фреймворк сессии Django
  • sindication: это фреймворк генерации фидов

Эти вложенные фреймворки очень упрощают нашу работу, независимо от того, создаем ли мы регистрацию и проверки подлинности, создаем страницу администрирования или предоставляем фиды для нашего содержимого. Пакет Django.contrib является очень важной частью Django. Знание его подпакетов и того, как их использовать, сэкономит вам много времени и усилий.

Этот раздел предоставит вам краткое введение в другие фреймворки в данном пакете. Не буду вдаваться в подробности о том, как пользоваться каждым фреймворком, но вы узнаете достаточно, чтобы знать, когда использовать фреймворк. После того, как вы захотите использовать фреймворки в проекте, вы можете прочитать онлайн-документацию, чтобы узнать больше о нем.

Flatpages

Веб-приложения могут содержать страницы, которые являются статическими по природе. Например, ваш сайт может включать набор страниц справки, которые редко изменяются. Django предоставляет приложение под названием flatpages для обслуживания статических страниц. Приложение является довольно простым; оно предоставляет вам модель данных для хранения различных битов информации о каждой странице, включая следующие:

  • URL-адрес
  • Название
  • Содержимое
  • Имя шаблона
  • Требуется ли регистрация для просмотра страницы

Чтобы использовать приложение, можно просто включить его в переменную INSTALLED_APPS в файле settings.py его middleware в переменную MIDDLEWARE_CLASSES. После этого можно хранить и управлять статическими страницами с помощью модели данных, предоставленной приложением flatpages.

HUMANIZE

Приложение humanize предлагает набор фильтров для добавления прикосновения человека к вашим страницам. Вот список доступных фильтров:

  • apnumber: для цифр 1-9, возвращает число прописью. В противном случае она возвращает само число. Другими словами, 1 становится "один", 9 становится "девять" и так далее, тогда как 10 остается 10.
  • intcomma: Принимает целое число и преобразует его в строку с запятой, например:

4500 становится 4500.

45000 становится 45,000.

450000 становится 450,000.

4500000 становится 4,500,000.

1000000 становится 1,0 млн.

1200000 становится 1,2 млн.

1200000000 становится 1,2 млрд.

25 Янв 2007 вчера.

26 Янв 2007 сегодня

27 Янв 2007 завтра

26 Jan 2007 16:30:00 сейчас.

26 Jan 2007 16:29:31 29 seconds ago.

26 Jan 2007 16:29:31 29 seconds ago.

26 Jan 2007 16:25:35 4 минуты назад

26 Jan 2007 15:30:29 59 минут назад

26 Jan 2007 15:30:01 59 минут назад

26 Jan 2007 15:30:00 1 час назад

26 Jan 2007 13:31:29 2 часа назад

25 Jan 2007 13:31:29 1 день, 2 часа назад

25 Jan 2007 13:30:01 1 день, 2 часа назад

25 Jan 2007 13:30:00 1 день, 3 часа назад

26 Jan 2007 16:30:30 будет через 30 секунд

26 Jan 2007 16:30:29 будет через 30 секунд

26 Jan 2007 16:31:00 будет через 1 минуту

26 Jan 2007 16:34:35 будет через 4 минуты

26 Jan 2007 17:30:29 будет через 1 час

26 Jan 2007 18 : 31:29 будет через 2 часа

27 Jan 2007 16 : 31:29 будет через 1 день

Sitemap

Sitemap — это фреймворк для создания карты сайтов, являющихся XML-файлами, которые помогают индексаторам поисковых движков находить динамические страницы на вашем сайте. Он указывает индексатору насколько страница важна и как часто она меняется. Эта информация делает процесс индексирования более точным и эффективным.

Фреймворк sitemaps позволяет выразить предыдущую информацию в коде Python , а затем генерирует XML-документ, который представляет карту вашего сайта. Это охватывает все наиболее часто используемые фреймворки из пакета django contrib. В пакете содержатся дополнительные приложения, которые не так важны, как предыдущие и он время от времени обновляется с новыми приложениями. Для того, чтобы узнать о любом приложения из пакета django contrib, вы можете всегда прочитать его документацию, которая доступна онлайн.

Читайте также: