我试图弄清楚Django ORM,并且我对表联接的等价物感到有些困惑。
假设我有以下三个模型,缩写为可读性。 "用户"是开箱即用的Django用户模型," AppUser"是一个相应的模型,用于存储其他个人资料信息,如邮政编码," Group"是一组用户(请注意,该组与身份验证组无关)。每个AppUser与每个用户都有一对一的关系。同样,每个AppUser也指向该用户所属的组(可以是None)。
我的任务:给定group_id,生成所有成员电子邮件的列表。
我知道我可以"向后移动一级"从Group到AppUser使用.appuser_set.all()
,但我不知道如何进一步获取相关用户及其电子邮件,而无需迭代并以非常严重的数据库方式执行此操作:
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"
答案 0 :(得分:2)
诀窍是始终从您实际想要获取的模型开始。在这种情况下,您想要获取电子邮件,这是用户模型上的字段。因此,从该模型开始,并使用双下划线语法来跟踪与Group的关系:
users = User.objects.filter(appuser__group_id=group_id)
在这种情况下,实际上只需要一个JOIN,因为group_id
是AppUser本身的一个字段(它是group
ForeignKey的基础db字段)。如果您有组名,则需要两个连接:
users = User.objects.filter(appuser__group__name=group_name)