Мне нужно выполнить отфильтрованный запрос из шаблона django, чтобы получить набор объектов, эквивалентных коду python в представлении:
queryset = Modelclass.objects.filter(somekey=foo)
В моем шаблоне я бы хотел сделать
{% for object in data.somekey_set.FILTER %}
но я просто не могу понять, как писать ФИЛЬТР.
Я просто добавляю дополнительный тег шаблона, например:
@register.filter def in_category(things, category): return things.filter(category=category)
Тогда я могу:
{% for category in categories %} {% for thing in things|in_category:category %} {{ thing }} {% endfor %} {% endfor %}
источник
'for' statements should use the format 'for x in y': for p in r | people_in_roll_department:d
. Есть идеи?Я регулярно сталкиваюсь с этой проблемой и часто использую решение «добавить метод». Тем не менее, определенно существуют случаи, когда «добавить метод» или «вычислить его в представлении» не работают (или работают плохо). Например, когда вы кэшируете фрагменты шаблона и для его создания требуется нетривиальное вычисление БД. Вы не хотите выполнять работу с БД, если вам это не нужно, но вы не узнаете, нужно ли вам это, пока не углубитесь в логику шаблона.
Некоторые другие возможные решения:
Используйте тег шаблона {% expr <expression> как <var_name>%}, который можно найти на http://www.djangosnippets.org/snippets/9/ Выражение - это любое допустимое выражение Python с контекстом вашего шаблона в качестве локальной области видимости.
Измените свой шаблонный процессор. Jinja2 ( http://jinja.pocoo.org/2/ ) имеет синтаксис, почти идентичный языку шаблонов Django, но с полной доступностью Python. Так же быстрее. Вы можете сделать это оптом или ограничить его использование шаблонами, над которыми вы работаете, но используйте «более безопасные» шаблоны Django для страниц, поддерживаемых дизайнером.
источник
Другой вариант заключается в том, что если у вас есть фильтр, который вы всегда хотите применять, добавить настраиваемого менеджера к рассматриваемой модели, который всегда применяет фильтр к возвращаемым результатам.
Хорошим примером этого является
Event
модель, в которой для 90% запросов, которые вы выполняете по модели, вам понадобится что-то подобноеEvent.objects.filter(date__gte=now)
, т. Е. Обычно это вас интересуетEvents
. Это выглядело бы так:class EventManager(models.Manager): def get_query_set(self): now = datetime.now() return super(EventManager,self).get_query_set().filter(date__gte=now)
А в модели:
class Event(models.Model): ... objects = EventManager()
Но опять же, это применяет один и тот же фильтр ко всем запросам по умолчанию, выполняемым в
Event
модели, и поэтому не так гибки некоторые из описанных выше методов.источник
Это можно решить с помощью тега присвоения:
from django import template register = template.Library() @register.assignment_tag def query(qs, **kwargs): """ template tag which allows queryset filtering. Usage: {% query books author=author as mybooks %} {% for book in mybooks %} ... {% endfor %} """ return qs.filter(**kwargs)
источник
Для всех, кто ищет ответ в 2020 году. У меня это сработало.
В просмотрах:
class InstancesView(generic.ListView): model = AlarmInstance context_object_name = 'settings_context' queryset = Group.objects.all() template_name = 'insta_list.html' @register.filter def filter_unknown(self, aVal): result = aVal.filter(is_known=False) return result @register.filter def filter_known(self, aVal): result = aVal.filter(is_known=True) return result
В шаблоне:
{% for instance in alarm.qar_alarm_instances|filter_unknown:alarm.qar_alarm_instances %}
В псевдокоде:
For each in model.child_object|view_filter:filter_arg
Надеюсь, это поможет.
источник