如何在 Django 中过滤加入的模型?
Posted
技术标签:
【中文标题】如何在 Django 中过滤加入的模型?【英文标题】:How to filter joined models in Django? 【发布时间】:2018-07-19 00:38:58 【问题描述】:我有以下型号:
class Street(models.Model):
name = models.CharField(max_length=40)
class House(models.Model):
street = models.ForeignKey(Street, models.PROTECT)
number = models.CharField(max_length=10)
class Meta:
unique_together = ('street', 'number')
class Room(models.Model):
house = models.ForeignKey(House, models.PROTECT)
number = models.CharField(max_length=10)
class Meta:
unique_together = ('house', 'number')
我已经知道Street
的 ID,并且想获得那条街上所有房屋的所有房间。在 SQL 中很简单:
SELECT *
FROM room JOIN house ON house.id = room.house_id
WHERE house.street_id = xyz;
现在我如何在 Django 中做到这一点?我试过了
Room.objects.select_related('house').filter(street=xyz)
但我收到一个异常,说我无法访问此字段:
django.core.exceptions.FieldError: Cannot resolve keyword 'street' into field. Choices are: house, house_id, id, number
由于我面临的数据量很大,我真的希望能够使用单个查询进行连接和过滤!当放弃其中一个时,我将不得不求助于进行多个查询或在 Python 中进行过滤,这两者本质上都是低效的。我猜另一种方法是原始查询...
【问题讨论】:
filtering across relationships 上有一整段文档。 【参考方案1】:您可以使用__
语法访问相关对象的字段:
Room.objects.select_related('house').filter(house__street=xyz)
这可以根据您的需要尽可能多地完成,要按街道名称选择房间,您可以这样做:
Room.objects.select_related('house').filter(house__street__name=xyz)
查看详细信息here。
【讨论】:
注意,您不需要select_related
来使过滤器在连接模型上工作。
酷。我完全错过了文档中最明显的部分。即使是左外连接也能像魅力一样工作!
@DanielRoseman 我是否也将相关连接放入select_related
是否真的很重要?它会选择不必要的字段吗?
@purefanatic slect_related
允许您一次查询获取相关对象的数据。如果您不需要房子的详细信息,您可以删除 select_related。在这种情况下,filter(house__street=xyz)
也可以使用。但是,如果您稍后在代码中使用room.house
,它将再次影响数据库。更多详情:docs.djangoproject.com/en/2.0/ref/models/querysets/…以上是关于如何在 Django 中过滤加入的模型?的主要内容,如果未能解决你的问题,请参考以下文章