2011-11-02 102 views
4

我们有一个Django DetailView,我们正在显示一个对象(Site)及其所有相关对象(Rooms)。Django - 在模板中过滤RelatedManager _set

现在,在模板中,我们可以简单地在RelatedManager集迭代:

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

然而,这样做的问题是,这将拿起所有相关房间的网站 - 然而,我们需要通过另一个属性(我们称之为year)将此设置缩小一些 - 并且此属性存储在Django会话变量中。

目前,我们只是在视图代码中使用Room.objects.filter(site=some_site, year='2009'),这很好。

我的问题更多来自好奇心 - 有没有什么办法在模板中使用_set,并仍然过滤或缩小集合?

您可以编写一个自定义模型管理器来执行此操作,以便_set只会返回当前年份的对象吗?或者有其他方法吗?

干杯, 维克多

回答

2

我的问题是从好奇更多 - 有没有办法使用_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)