Правильный способ добавить запись ко многим отношениям в Джанго - PullRequest
3 голосов
/ 01 января 2011

Прежде всего, я планирую запустить свой проект на движке приложений Google, поэтому я использую djangoappengine , который, насколько я знаю, не поддерживает тип ManyToManyField django.Из-за этого я настроил свои модели следующим образом:

from django.db import models
from django.contrib.auth.models import User

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

class UserGroup(models.Model):
    user = models.ForeignKey(User)
    group = models.ForeignKey(Group)

На странице у меня есть поле формы, где люди могут ввести имя группы.Я хочу, чтобы результаты из этого поля формы создавали объект UserGroup для комбинации пользователь-группа, и, если группа еще не существует, создайте новый объект Group.Сначала я начал помещать эту логику в класс UserGroup с помощью метода add_group, но быстро понял, что на самом деле нет смысла помещать это в класс UserGroup.Каков будет правильный способ сделать это?Я видел кое-что о моделях менеджеров.Это для чего они нужны?

1 Ответ

3 голосов
/ 01 января 2011

Из документов Django :

Менеджер - это интерфейс, через который предоставляются операции запросов к базе данных для моделей Django

Таким образом, менеджер не является способом создания новых экземпляров модели.

Я бы просто имел конструктор для модели Group, который извлекает User (если он задан) из аргументов ключевого слова и создает новый UserGroup.

Таким образом, если вы создали новый Group как Group(name='group name', user=some_user), конструктор мог бы убрать аргумент ключевого слова user и создать соответствующий UserGroup с этим user:

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

    def __init__(self, *args, **kwargs):
        # Remove user from the kwargs.
        # It is important that user is removed from the kwargs before calling
        # the super.__init__(). This is because the `user` kwarg is not expected.
        user = kwargs.pop('user', None)

        # call the normal init method
        super(Group, self).__init__(*args, **kwargs)

        # Create the UserGroup instance for the specified user
        if user is not None:
            # Maybe some other logic here ...
            UserGroup(user=user, group=self).save()

Таким образом, если вы предоставите user при создании экземпляра Group, он создаст UserGroup и не будет ничего делать в противном случае.

Конечно, вы могли бы сделать то же самое в конструкторе модели UserGroup, это не так уж важно, это просто зависит от того, что метафорически имеет смысл для вашего кода.

EDIT:

Исправление проблем, указанных в комментариях:

...
def __init__(self, *args, **kwargs):
    ...
    self._user_group = UserGroup(user=user, group=self)

def save(self, *args, **kwargs):
    super(Group, self).save(*args, **kwargs)
    self._user_group.save()
...