Django:如何基于子模型的过滤器查询父模型? [英] Django: how to query parent model based on a filter of a child model?

查看:65
本文介绍了Django:如何基于子模型的过滤器查询父模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有那些类(为清楚起见而简化了):

I have those classes (simplified for sake of clarity):

class Entity(models.Model):
    adresses = models.ManyToManyField(Address,
                                      related_name='persons',
                                      through='EntityAddress')

class EntityAddress(models.Model):
    entity = models.ForeignKey(Entity, on_delete=models.CASCADE,
                               blank=False, null=False)
    address_type = models.ForeignKey(AddressType, models.CASCADE,
                                     blank=False, null=False)
    address = models.ForeignKey(Address, on_delete=models.CASCADE,
                                blank=False, null=False)

class Address(models.Model):
    summary = models.CharField(max_length=250, blank=True, null=True)
    way = PolygonField(default=None, blank=True, null=True)

class Person(Entity):
    user = models.OneToOneField(User, blank=False, null=False,
                                on_delete=models.CASCADE)

我想让所有 Person 的地址都具有不为空"的 way .

I want to have all Person's whose addresses have a "not null" way.

我这样做是这样的:

for p in Person.objects.all():
    for e_a in EntityAddress.objects.filter(entity=p,
                                            address__way__isnull=False,):
        # do whatever here:
        pass

这太慢了!有没有办法只提出一个请求?

This is way too slow! Is there a way to make only one request?

推荐答案

您可以使用类似的东西:

not_null_ea = Entity.objects.filter(addresses__way__isnull=False).values('addresses')
for p in Person.objects.filter(
        addresses__in=not_null_ea).prefetch_related('entityaddress_set):
    for a_e in p.entityaddress_set:
        pass

这样,至少您不会自己遍历Person对象,这确实很慢.

This way at least you would not be looping through Person objects yourself which really is quite slow.

这篇关于Django:如何基于子模型的过滤器查询父模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆