我有以下型号:
class Foo(models.Model)
bar = models.ForeignKey(Bar, on_delete=models.PROTECT)
class Bar(models.Model)
...
class Baz(models.Model)
bar = models.ForeignKey(Bar, on_delete=models.PROTECT)
我想知道是否可以做一些类似于批注的操作来将Baz
查询集链接到预先过滤的Foo
查询集。像这样:
queryset = Foo.objects.some_filter()
.annotate(bazs=QuerySet('bar__baz_set.another_filter()'))
请注意,Baz
查询集也已过滤,并且Bar
可能并不总是具有Baz
这是我希望在模板中实现的:
{% for foo in queryset %}
...
{% for baz in foo.bazs %}
...
答案 0 :(得分:1)
您要寻找的是prefetch_related
和Prefetch
from django.db.models import Prefetch
queryset = Foo.objects.prefetch_related(
Prefetch(
'bar__baz_set',
queryset=Baz.objects.filter(another_filter),
to_attr='filtered_baz',
)
)
这是您在模板中使用它的方式:
{% for foo in queryset %}
...
{% for baz in foo.bar.filtered_baz %}
...
答案 1 :(得分:0)
这是一个更简单的替代解决方案,但正如其他答案的注释所指出的那样,查询数量有所增加。
class Foo(models.Model):
bar = models.ForeignKey(Bar, on_delete=models.PROTECT)
...
@cached_property
def bar_bazs(self):
return self.bar.get_bazs_by_some_filter()
class Bar(models.Model):
...
def get_bazs_by_some_filter(self):
return self.baz_set.some_filter()
在模板中:
{% for foo in queryset %}
...
{% for baz in foo.bar_bazs %}
...