Django中的ManyToOneField

时间:2009-05-20 15:15:55

标签: python django

我正在尝试在类中定义多对一字段,即“Many”。例如,假设用户只能是一个组的成员但组可以有许多用户的情况:

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 docs将告诉用户模型中的组字段定义为ForeignKey,但我需要在Group模型中定义关系。据我所知,没有ManyToOneField,我宁愿不必使用ManyToManyField。

3 个答案:

答案 0 :(得分: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简单得多。

答案 1 :(得分:1)

假设Users构造是内置的身份验证系统......我建议创建某种类型的Profile模型并将OneToMany字段附加到它上面。然后,您可以hook the Profile model to the user model

答案 2 :(得分: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 }}