ManyToOneField в Джанго - PullRequest
       5

ManyToOneField в Джанго

7 голосов
/ 20 мая 2009

Я пытаюсь определить поле «многие к одному» в классе «Многие». Например, представьте ситуацию, когда пользователь может быть членом только одной группы, но в группе может быть много пользователей:

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 скажет определить групповое поле в модели User как ForeignKey, но мне нужно определить отношение в модели Group. Насколько я знаю, ManyToOneField не существует, и я бы предпочел не использовать ManyToManyField.

Ответы [ 3 ]

10 голосов
/ 20 мая 2009
Поле

A 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, вы бы в любом случае смоделировали эту связь с внешним ключом из пользовательской таблицы в таблицу групп, если это помогает думать об этом таким образом. Синтаксис и логика использования свойства ManyToOne, определенного в экземпляре группы, если бы существовала такая концепция, было бы гораздо проще, чем ForeignKey, определенный для пользователя.

1 голос
/ 20 мая 2009

Вы, вероятно, должны смотреть просто используя встроенные обратные поиски:

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 голос
/ 20 мая 2009

Предполагая, что конструкция Users является встроенной системой аутентификации ... Я бы порекомендовал создать некую модель Profile и вместо нее прикрепить к ней поле OneToMany. Затем вы можете подключить модель профиля к пользовательской модели .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...