如何在 Django 中获得一组对象的反向关系?

how to get backward relation for a set of objects in django?

我有城市和省的模型:

class Province(Model):
    name = CharField(...)


class City(Model):
    name = CharField(...)
    province = ForeignKey(Province,......, related_name='cities')

假设我按如下方式填充了数据库:

ontario = Province.objects.create(name='Ontario')
quebec = Province.objects.create(name='Quebec')
alberta = Province.objects.create(name='alberta')
toronto = City.objects.create(province=ontario, name='Toronto')
waterloo = City.objects.create(province=ontario, name='Waterloo')
montreal = City.objects.create(province=quebec, name='Montreal')
calgary = City.objects.create(province=alberta, name='Calgary')

我可以检索安大略省所有城市的查询集,如下所示:

ontario.cities.all()

上面的查询集中有两个对象:toronto和waterloo 我如何获得安大略省和魁北克省所有城市的查询集? 假设我有一个包含安大略省和魁北克省的查询集,例如:

my_province_query = Province.objects.exclude(name__contains="Alberta")

我想使用此查询集获取多伦多、滑铁卢和蒙特利尔

我首先尝试了 my_province_query.objects.all() 但不可能这样做,因为查询不是获取其对象的模型。有什么建议吗? 请注意,我需要单个查询集中的所有对象。我想到了 运行 两个不同的查询,然后将它们合并在一起,但我正在寻找更好的方法

如果您只需要城市名称,查询可能如下所示:

city_names = Province.objects.exclude(name__contains="Alberta").values_list('cities__name', flat=True)
# city_names == <QuerySet ['Toronto', 'Waterloo', 'Montreal']>

如果您需要实际的 City 个实例,您可以 select City pks 然后 select 使用另一个查询的实例:

city_pks = Province.objects.exclude(name__contains="Alberta").values_list('cities__pk', flat=True)
cities = City.objects.filter(pk__in=city_pks)
# cities == <QuerySet [<City: Toronto>, <City: Waterloo>, <City: Montreal>]

如果你想让 City 个实例只访问一次数据库,你必须使用 City Manager:

来编写你的查询
from django.db.models import Q

cities = City.objects.filter(~Q(province__name__in=['Alberta']))
# cities == <QuerySet [<City: Toronto>, <City: Waterloo>, <City: Montreal>]>