查询集中相关manytomany字段的具体加载

问题描述 投票:1回答:2

我正在使用具有多对多关系的额外字段的中间模型,如下所示:

class A(models.Model):
    name = models.CharField(max_length=128)

class B(models.Model):
    name = models.CharField(max_length=128)
    a = models.ManyToManyField(A, through='AB')

class AB(models.Model):
    a = models.ForeignKey(A, on_delete=models.CASCADE)
    b = models.ForeignKey(B, on_delete=models.CASCADE)
    number = models.IntegerField(default=0)
    date = models.DateTimeField()

默认情况下,AB.date在数据库中为NULL。

我用这样的B检索我所有的B.objects.all()实例。

然后,对于B的每个实例,我可以得到一组像这样的ABb_instance.ab_set.all()

如何只加载ab_set为空的date元素?

在SQL中,它看起来像这样:

SELECT * FROM B
INNER JOIN AB ON AB.id = B.ab_id AND AB.date IS NULL
django many-to-many django-queryset django-orm
2个回答
1
投票

您可以使用__isnull [doc]字段查找执行过滤器,例如:

b_instance.ab_set.filter(date__isnull=True)

因此我们通过指定.filter(..)字段date来设置isnull

或者,如果您想要使用非None date进行查询,则可以使用date=None进行过滤:

b_instance.ab_set.filter(date=None)

0
投票

通过对我的问题的一些研究,我终于找到了可以解决问题的东西。

我使用Model method来过滤我的一组对象:

class B(models.Model):
    ...
    def get_ab_with_null_date(self):
        return self.ab_set.filter(date__isnull=True)

所以,我可以在我的模板中过滤ab_set,如下所示:

{% for b in list_of_B %}
    {% for ab in b.get_ab_with_null_date %}
        ...
    {% endfor %}
{% endfor %}

你认为有更有效的方法来执行此操作吗?

另外,我看到一些关于覆盖Manager的事情:

b = B.objects.get(...)
b.custom_manager.get_ab_with_null_date() # return filtered ab_set with null date

由于我没有直接在视图中操纵我的ab_set,我认为这对我的情况不太有用。

© www.soinside.com 2019 - 2024. All rights reserved.