tags:

views:

294

answers:

3

I'm trying to define a many-to-one field in the class that is the "Many". For example, imagine a situation where a user can only be a member of one group but a group can have many users:

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 will tell to define a group field in the User model as a ForeignKey, but I need to define the relationship in the Group model. As far as I know, there isn't a ManyToOneField and I would rather not have to use a ManyToManyField.

+6  A: 

A ManyToOne field, as you've guessed, is called ForeignKey in Django. You will have to define it on your User class for the logic to work properly, but Django will make a reverse property available on the Groups model automatically:

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

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

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

Remember that Django's models sit on top of a relational database... there's no way to define a single FK field in a table that points to more than one foreign key (without a M2M, that is), so putting the ManyToOne relationship on the Groups object doesn't map to the underlying data store. If you were writing raw SQL, you'd model this relationship with a foreign key from the user table to the group table in any event, if it helps to think of it that way. The syntax and logic of using a ManyToOne property that is defined on a Group instance, if such a concept existed, would be much less straightforward than the ForeignKey defined on User.

Jarret Hardie
Thanks for explaining why it wasn't possible to do what I was looking for. I'm just going to use a many to many field.
vacanti
+1  A: 

Assuming that the Users construct is the built-in authentication system... I would recommend creating a Profile model of some sort and attaching the OneToMany field to it instead. You can then hook the Profile model to the user model.

R. Bemrose
+1  A: 

You should probably be looking at simply using built in reverse lookups:

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

Reverse lookup sets are automatically created for any foreign keys or many-to-many relationships to the model in question.

If you want to refer to this with a friendlier name, or provide additional filtering before returning, you can always wrap the call in a method:

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

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

Either can be called from the templates:

{{ group.user_set.all }}

{{ group.users }}
Soviut
Thanks! This is what I'm using with the ManyToMany field in the Group class.
vacanti