我创建了一个模型管理器,可以过滤数据
class BOMVersion_default_active_Manager(models.Manager):
def get_queryset(self):
return super(BOMVersion_default_active, self).get_queryset().filter(is_default=True,is_active=True)
@with_author
class BOMVersion(models.Model):
version = IntegerVersionField( )
name = models.CharField(max_length=200,null=True, blank=True)
description = models.TextField(null=True, blank=True)
material = models.ForeignKey(Material)
default_active_objects = BOMVersion_default_active_Manager()
我尝试在模板的嵌套for循环中使用它(因为我无法直接在模板中过滤,这就是我决定克服这个限制的方法)
{% for bomversion in soproduct.product.material.bomversion.default_active_objects_set.all %}
但我没有得到任何输出。可能是什么问题呢?我可以这样做吗?
答案 0 :(得分:1)
使用自定义Manager
不是正确的方法。您需要仔细阅读整篇Django Managers文章。
在这种情况下,您需要的是自定义QuerySet
。像这样:
class BOMVersionQuerySet(models.QuerySet):
def active(self):
return self.filter(is_active=True)
def default(self):
return self.filter(is_default=True)
@with_author
class BOMVersion(models.Model):
version = IntegerVersionField( )
name = models.CharField(max_length=200,null=True, blank=True)
description = models.TextField(null=True, blank=True)
material = models.ForeignKey(Material)
objects = BOMVersionQuerySet.as_manager()
现在,您可以使用.active()
和.default()
方法过滤任何BOMVersion-QuerySet
。这实际上是您使用Material
模型中的反向关系时得到的结果,material.bomversion_set
是BOMVersion-QuerySet
,因此您无法访问BOMVersion.objects
,但是因为它BOMVersion-QuerySet
您可以使用.active()
和.default()
{% for bomversion in soproduct.product.material.bomversion_set.default.active %}
然而,这又是完全错误的,我的建议是不要在模板中这样做。使用视图构建查询集,并仅在模板中迭代它们。
为什么它在模板中不好?因为您现在每个material
对象进行1次查询,除非您使用prefetch_related
,否则无法对其进行优化,但猜猜是什么?您不能在django模板系统中使用prefetch_related
。 (它是故意的,原因是不要在模板中做那样的事情),所以正确的方法是做出类似的东西:
#in the view:
soproduct = SoProduct.objects.select_related('product__material').prefetch_related(
Prefetch(
'product__material__bomversion_set',
queryset=BOMVersion.objects.default().active()
to_attr='default_active_bomversions'
)
).get(pk=soproduct_id)
#in the template:
{% for bomversion in soproduct.product.material.default_active_bomversions %}
现在,您将对soproduct
及其相关的product
和material
数据进行1次查询,并对请求的default_active_bomversions
进行1次查询。