Note that there are some explanatory texts on larger screens.

plurals
  1. POIs save_m2m() required in the Django forms save() method when commit=False?
    primarykey
    data
    text
    <p>The docs seem pretty firm that this is indeed the case....</p> <p><a href="https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method" rel="nofollow">https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method</a></p> <p>And I specifically refer to this section:</p> <blockquote> <p>Another side effect of using commit=False is seen when your model has a many-to-many relation with another model. If your model has a many-to-many relation and you specify commit=False when you save a form, Django cannot immediately save the form data for the many-to-many relation. This is because it isn't possible to save many-to-many data for an instance until the instance exists in the database.</p> <p>To work around this problem, every time you save a form using commit=False, Django adds a save_m2m() method to your ModelForm subclass. After you've manually saved the instance produced by the form, you can invoke save_m2m() to save the many-to-many form data.</p> </blockquote> <p>I am pretty new to django and stumbled upon this information yesterday.</p> <p>However, I have a view where I do not invoke the save_m2m() method but it does in fact save the m2m data. </p> <p>Here is my view:</p> <pre><code>class SubscriberCreateView(AuthCreateView): model = Subscriber template_name = "forms/app.html" form_class = SubscriberForm success_url = "/app/subscribers/" def get_form_kwargs(self): kwargs = super(SubscriberCreateView, self).get_form_kwargs() kwargs.update({'user': self.request.user}) return kwargs def form_valid(self, form): self.object = form.save(commit=False) self.object.user = self.request.user try: self.object.full_clean() except ValidationError: form._errors["email"] = ErrorList([u"This subscriber email is already in your account."]) return super(SubscriberCreateView, self).form_invalid(form) return super(SubscriberCreateView, self).form_valid(form) </code></pre> <p>My model:</p> <pre><code>class Subscriber(models.Model): STATUS_CHOICES = ( (1, ('Subscribed')), (2, ('Unsubscribed')), (3, ('Marked as Spam')), (4, ('Bounced')), (5, ('Blocked')), (6, ('Disabled')), ) user = models.ForeignKey(User) status = models.IntegerField(('status'), choices=STATUS_CHOICES, default=1) email = models.EmailField() subscriber_list = models.ManyToManyField('SubscriberList') first_name = models.CharField(max_length=70, blank=True) last_name = models.CharField(max_length=70, blank=True) phone = models.CharField(max_length=20, blank=True) facebook_id = models.CharField(max_length=40, blank=True) twitter_id = models.CharField(max_length=40, blank=True) address1 = models.CharField(max_length=100, blank=True) address2 = models.CharField(max_length=100, blank=True) postcode = models.CharField(max_length=10, blank=True) city = models.CharField(max_length=30, blank=True) country = models.CharField(max_length=30, blank=True) date_joined = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) class Meta: unique_together = ( ('user', 'email',), ) def __unicode__(self): return self.email </code></pre> <p>My form:</p> <pre><code>class SubscriberForm(ModelForm): def __init__(self, user, *args, **kwargs): super (SubscriberForm, self).__init__(*args, **kwargs) self.fields['subscriber_list'].queryset = SubscriberList.objects.filter(user=user) class Meta: model = Subscriber exclude = ('user', 'facebook_id', 'twitter_id') </code></pre> <p>Why does my view work, then? (meaning, the m2m relation of one of the fields in the form is in fact saved when the form is processed.)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload