Django 多对多字段过滤器列表
Posted
技术标签:
【中文标题】Django 多对多字段过滤器列表【英文标题】:Django manytomany field filter list 【发布时间】:2016-12-13 16:21:16 【问题描述】:我正在打印与某些过滤器匹配的啤酒列表,以及每个都可以点击的酒吧。这些是多对多关系。我需要过滤此条形列表以仅显示处于给定状态的条形。
我可以使用模板中的 if 语句来实现这一点,但是我无法将列表格式化为在最后一项之前使用带有“和”的逗号(如 https://***.com/a/3649002/6180992),因为我不知道列表。
我已经想到了三种可能的方法,但无法使任何一种工作:
过滤与酒吧相关的字段以及视图中的啤酒 在模板中组装列表,然后再次循环打印它 过滤模板中的条形相关字段以下是相关的代码部分:
models.py
class Bar(models.Model):
bar = models.CharField(max_length=200, default='FinshnPig')
state = models.CharField(max_length=200,default='NY')
def __str__(self):
return self.bar
class Meta:
ordering = ('bar','region')
class Tap(models.Model):
bar = models.ManyToManyField(Bar,default='FinshnPig')
brewery = models.CharField(max_length=200)
beer = models.CharField(max_length=200)
state = models.CharField(max_length=200, default='NY')
def __str__(self):
return self.beer
views.py
f = TapFilter(request.GET, queryset=Tap.objects.filter(state="VIC"))
模板:
% for tap in filter %
<li>
<b> tap.beer </b>
<em> tap.brewery </em>
@% for bar in tap.bar.all %% if bar.state == "VIC" % bar.bar </b>% endif %% include "taplists/comma.html" %% endfor %
</li>
% endfor %
【问题讨论】:
【参考方案1】:您可以使用prefetch 只查询相关栏,然后再将其发送到模板,如下所示:
prefetch = Prefetch(
'bar',
queryset=Bar.objects.filter(state=CHOSEN_STATE),
to_attr='selected_states'
)
filter = Tap.objects.filter(state=CHOSEN_STATE).prefetch_related(prefetch)
现在在您的模板中使用您分配的自定义属性:
% for tap in filter %
# Now selected_bars only contains the bars in the state you want
% for bar in tap.selected_bars.all %
...
% endfor %
% endfor %
prefetch_related 的 Django 文档的其他信息
注意:对ManyToMany
关系使用预取也会提高性能,因为不会有那么多数据库查找。
【讨论】:
谢谢!我只需要删除模板中的 .all,否则效果非常好!以上是关于Django 多对多字段过滤器列表的主要内容,如果未能解决你的问题,请参考以下文章