Python 使用Django ORM进行表联接
我试图找出Django ORM,但我对表连接的等价物有点困惑 假设我有以下三个模型,为便于阅读而缩写。“User”是现成的Django用户模型,“AppUser”是存储其他配置文件信息(如邮政编码)的对应模型,“Group”是用户的集合(请注意,此组与身份验证组无关)。每个AppUser与每个用户都有一对一的关系。类似地,每个AppUser还指向该用户所属的组(可能没有) 我的任务:给定组id,生成所有成员电子邮件的列表 我知道我可以使用Python 使用Django ORM进行表联接,python,django,orm,model,Python,Django,Orm,Model,我试图找出Django ORM,但我对表连接的等价物有点困惑 假设我有以下三个模型,为便于阅读而缩写。“User”是现成的Django用户模型,“AppUser”是存储其他配置文件信息(如邮政编码)的对应模型,“Group”是用户的集合(请注意,此组与身份验证组无关)。每个AppUser与每个用户都有一对一的关系。类似地,每个AppUser还指向该用户所属的组(可能没有) 我的任务:给定组id,生成所有成员电子邮件的列表 我知道我可以使用.AppUser\u set.all()从一个组“向后遍历
.AppUser\u set.all()
从一个组“向后遍历一级”到另一个AppUser,但我不知道如何进一步获取相关用户及其电子邮件,而无需迭代并以这样的方式执行:
appUser = AppUser.objects.get(user_id=request.user.id)
group = appUser.group
appUsers = group.appuser_set.all()
emails = []
for x in appUsers:
emails.append(x.user.email)
或者,我可以编写一个原始的SQL连接来完成它,但我怀疑Django ORM是有能力的。
做这件事的正确和最有效的方法是什么
型号:
class User(Model):
id = IntegerField()
username = CharField()
email = CharField()
class Meta:
db_table = "auth_user"
class AppUser(Model):
user = OneToOneField(User, primary_key=True)
group = ForeignKey('Group', null=True, on_delete=SET_NULL)
zip = CharField()
class Meta:
db_table = "app_users"
class Group(Model):
creator = ForeignKey(AppUser, related_name='+')
created = DateTimeField()
name = CharField()
class Meta:
db_table = "groups"
诀窍是始终从实际要获取的模型开始。在本例中,您希望获取电子邮件,这是用户模型上的一个字段。因此,从该模型开始,使用双下划线语法来遵循分组关系:
users = User.objects.filter(appuser__group_id=group_id)
在这种情况下,实际上只需要一个连接,因为group\u id
是AppUser本身的一个字段(它是group
ForeignKey的底层db字段)。如果您有组名,则需要两个联接:
users = User.objects.filter(appuser__group__name=group_name)
在向查询中添加
values
或values\u list
子句时,也可以遵循fks,例如group.appuser\u set.values('user\u email')
。是酷。下划线语法一开始似乎很奇怪,但一旦你习惯了,我就可以看到它的实用性。我不得不将方法从all()改为filter(),但除此之外,它的工作方式非常出色。谢谢