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

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

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 ответ

Решение

Из документов 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 модель, это на самом деле не так важно, это просто зависит от того, что метафорически имеет смысл для вашего кода.

РЕДАКТИРОВАТЬ:

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

...
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()
Другие вопросы по тегам