Django中的ManyToOneField

7 投票
3 回答
6817 浏览
提问于 2025-04-15 11:43

我想在一个类中定义一个多对一的字段,这个类是“多”的那一方。举个例子,想象一下一个场景:一个用户只能属于一个组,但一个组可以有很多用户。

class User(models.Model):
    name = models.CharField()

class Group(models.Model):
    name = models.CharField()
    # This is what I want to do -> users = models.ManyToOneField(User)

在Django的文档中,会告诉你在用户模型中定义一个组字段,使用外键(ForeignKey),但我需要在组模型中定义这个关系。就我所知,并没有一个叫做ManyToOneField的东西,我也不想使用ManyToManyField。

3 个回答

1

你可能应该考虑直接使用内置的反向查找功能:

group = Group.objects.get(id=1)
users_in_group = group.user_set.all()

对于任何外键或多对多关系,系统会自动创建反向查找集合。

如果你想用一个更友好的名字来引用这个,或者在返回之前提供额外的过滤条件,你可以把这个调用放在一个方法里:

class Group(models.Model):
    name = models.CharField(max_length=64)

    def users(self):
        return self.user_set.all()

这两种方法都可以在模板中调用:

{{ group.user_set.all }}

{{ group.users }}
1

假设用户构造是内置的认证系统……我建议你创建一个个人资料模型,然后把“一对多”字段连接到这个模型上。这样你就可以把个人资料模型和用户模型连接起来

10

你猜得没错,ManyToOne 字段在 Django 中叫做 ForeignKey。你需要在你的 User 类里定义它,这样逻辑才能正常工作。不过,Django 会自动在 Groups 模型上提供一个反向属性。

class Group(models.Model):
    name = models.CharField(max_length=64)

class User(models.Model):
    name = models.CharField(max_length=64)
    group = models.ForeignKey(Group)

g = Group.objects.get(id=1)
print g.user_set.all()  # prints list of all users in the group

记住,Django 的模型是建立在关系型数据库之上的……在一个表里定义一个指向多个外键的单一 FK 字段是行不通的(除非使用 M2M,即多对多关系),所以把 ManyToOne 关系放在 Groups 对象上并不能映射到底层的数据存储。如果你在写原始 SQL,实际上你会用一个外键把用户表和组表连接起来,这样想可能会更有帮助。如果有一个概念是定义在 Group 实例上的 ManyToOne 属性,它的语法和逻辑会比在 User 上定义的 ForeignKey 要复杂得多。

撰写回答