表连接使用Django ORM

时间:2014-05-02 16:01:36

标签: python django orm model

我试图弄清楚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"

1 个答案:

答案 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)