Создание экземпляра модели со множеством полей в Джанго - PullRequest
12 голосов
/ 23 декабря 2010

У меня есть метод, который работает, но он кажется очень неуклюжим, и я думаю, что есть лучший способ сделать это.

У меня есть Модель, которая связывает пользователя на моем сайте (клон твиттерав учебных целях) к списку других пользователей.

Прямо сейчас, когда я создаю нового пользователя, я хочу инициализировать этот список с пользователем в качестве члена списка.

моя модель:

class FollowerList(models.Model)
    follower = models.ForeignKey(User,related_name="follower")
    followed = models.ManyToManyField(User,related_name="followed"

код, который я использую сейчас, на мой взгляд,

user = User.objects.get(username=uname)
flst = FollowerList()
flst.follower = user
flst.save()
flst.followed.add(user)
flst.save()

Мне кажется, что там должен быть методом для создания этого без двойного вызова save (), но я не могу найти его в документации или где-либо еще.

Ответы [ 3 ]

12 голосов
/ 23 декабря 2010

Вам не нужно вызывать save после many2many.add ()

Вы также можете сократить код до 2 строк:

flst = FollowerList.objects.create(follower=user)
flst.followed.add(user)
4 голосов
/ 23 декабря 2010

Юджи ответ правильный.Вы не можете добавить объект в поле M2M, пока он не будет сохранен.Я хотел упомянуть более короткий способ создания экземпляров.

user = User.objects.get(username=uname)
flst = FollowerList(follower=user) #use key word args to assign fields
flst.save()
flst.followed.add(user)
# don't need to save after adding an object to many to many field.

Я считаю, что этот синтаксис немного лучше, чем создание пустого экземпляра и назначение полей.Хотя метод objects.create () (упомянутый Юки) еще приятнее.

2 голосов
/ 07 февраля 2015

Поздний ответ на этот : вы также можете переопределить конструктор (__init__) следующим образом:

class FollowerList(models.Model):
    follower = models.ForeignKey(User,related_name="follower")
    followed = models.ManyToManyField(User,related_name="followed"

    def __init__(*args, followed=[], **kwargs):
        super(FollowerList, self).__init__(*args, **kwargs)
        self.save()
        for user in followed:
            self.followed.add(user)

т.е. здесь я явно обработал ключевое слово followedаргумент в функции __init__, при этом все остальные args и kwargs передаются в конструктор по умолчанию.Вызов save гарантирует, что объект был зарегистрирован и, таким образом, может использоваться в отношении m2m.

Это позволяет затем создать FollowerList одной строкой, например,

flst = FollowerList(follower=user, followed=[user,])

В качестве альтернативы, как отметил Йоханнес, сохранение модели в __init__ не ожидается.Предпочтительным подходом было бы создать метод Manager - подробности см. Здесь: https://docs.djangoproject.com/en/1.9/topics/db/managers/, а затем создать FollowerList:

fl = FollowerList.objects.create(*args, followed, **kwargs)
...