Правильный способ добавить запись ко многим отношениям в Джанго
Прежде всего, я планирую запустить свой проект на движке приложений 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.
Таким образом, менеджер - это не способ создания новых экземпляров модели.
Я бы просто имел конструктор для 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()