Instantiate model instance with manytomany field in Django
A late answer to this: you could also override the constructor (__init__
) as follows:
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)
ie here I've explicitly handled the followed
keyword argument in the __init__
function, while passing all other args
and kwargs
on to the default constructor.
The call to save
makes sure that the object has been registered and can thus be used in an m2m relationship.
This then allows you to do create FollowerList
with one line, eg
flst = FollowerList(follower=user, followed=[user,])
Alternatively, as pointed out by Johannes, saving a model in the __init__
is not expected. The preferred approach would be to create a Manager
method - see here for details: https://docs.djangoproject.com/en/1.9/topics/db/managers/
and then to create a FollowerList
:
fl = FollowerList.objects.create(*args, followed, **kwargs)
You don't need to call save after the many2many.add()
You could also shorten the code to 2 lines:
flst = FollowerList.objects.create(follower=user)
flst.followed.add(user)
Yuji's answer is correct. You can not add an object to a M2M field until it has been saved. I wanted to mention a shorter way to create instances though.
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.
I find that syntax slightly nicer than creating an empty instance and assigning fields. Though the objects.create() method (mentioned by Yuki) is nicer still.