Reputation: 8418
I am trying to save/create a ManyToMany relation while saving my model. This is my code:
class Invoice(models.Model):
name = models.CharField(max_length=64)
product_ids = models.CharField(max_length=128, default='')
products = models.ManyToManyField(Product, null=True, blank=True)
def save(self, *args, **kwargs):
super(Invoice, self).save(*args, **kwargs)
if self.product_ids:
ids = self.product_ids.split(',')
for id in ids:
product = Product.objects.get(id=id)
self.products.add(product)
super(AllAroundCompetition, self).save(*args, **kwargs)
It is self explanatory. Sometimes I would like to create the invoice manually and I don't want to browse the whole list while pressing "ctrl" in order to select many products. So I have added a dumb extra field to pass ids in a comma separated manner (eg 25,27,90,20). This is product_ids
field. I overrode the save()
method to create these M2M relations. But it doesn't work. Invoice is created, but the relations are not.
What am I doing wrong?
(using django 1.5)
Upvotes: 0
Views: 648
Reputation: 235
M2M relation changes are saved in separate table in database. Therefore save method saves only model itself, relation is saved after changes to model has been made in proper table in database, e.g. when creating new model it has to be created in database (save method) to add M2M foreign keys.
TL;DR: Try overriding method ModelAdmin.save_related(self, request, form, formsets, change) (you may have to create model admin class for this model and registering it)
Upvotes: 1
Reputation: 6725
You are calling super(AllAroundCompetition, self).save(…)
at the bottom of your method. Adding an object to an m2m relation shouldn't need a save
call afterwards at all, and calling save
of another class might mess things up.
I suggest an alternative solution at all: try using a filter_horizontal
for your products
field in the admin. It has a nicer user interface, including search. No more ctrl-holding neccessary:
class InvoiceAdmin(admin.ModelAdmin):
filter_horizontal = ('products',)
Upvotes: 1