Django - фильтрация RelatedManager _set в шаблоне? - PullRequest
5 голосов
/ 02 ноября 2011

У нас есть Django DetailView, где мы отображаем объект (Site) вместе со всеми связанными с ним объектами (Rooms).

Теперь в шаблоне мы могли бы простоВыполните итерацию по набору RelatedManager:

{% for room in site.room_set.all %}
    do stuff
{% endfor %}

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

В настоящее время мы просто используем Room.objects.filter(site=some_site, year='2009') в коде представления, и это нормально.

Мой вопрос больше связан с любопытством - есть ли способ использовать _set в шаблоне и все же отфильтровать или сузить набор?

Не могли бы вы написать собственный Менеджер моделей, чтобы сделать это,так что _set будет когда-либо только возвращать объекты за текущий год?Или есть какой-то другой способ?

Ура, Виктор

1 Ответ

3 голосов
/ 02 ноября 2011

Мой вопрос больше связан с любопытством - есть ли способ использовать _set в шаблоне и все же отфильтровать или сузить набор?

Не по умолчанию, поскольку нет способапередать аргументы вызову фильтра.

  • Если это функциональность, которую нужно повторять по-разному , часто, и связанной с шаблоном: создайте пользовательский тег шаблона или фильтр (которыйможет принимать аргументы).
  • Если функциональность специфична для представления, закодируйте его в представлении.
  • Если функциональность одинакова для нескольких представлений, соберите функцию в сухом месте.

Для # 3 существует так много факторов, которые определяют, куда этот код должен идти, что нет общего решения.Вы могли бы импортировать функцию в ваши представления?Использовать менеджер моделей?Метод экземпляра модели?контекстный процессор?и т. д.

Не могли бы вы написать собственный Менеджер моделей для этого, чтобы _set возвращал только объекты текущего года?Или есть какой-то другой способ?

Похоже, что вы можете на самом деле, просто используя менеджер модели для своей обратной связанной модели.

class RoomManager(models.Manager):
    def current_year(self):
        return self.get_queryset().filter(year=datetime.date.today().year)

for room in site.room_set.current_year():
   ...

Или просто на родительской модели:

class Site(models.Model):
    ...
    def year_room_set(self):
        return self.room_set.filter(year=datetime.date.today().year)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...