Author: brosner
Date: 2008-07-15 17:41:17 -0500 (Tue, 15 Jul 2008)
New Revision: 7930

Modified:
   django/branches/newforms-admin/django/newforms/models.py
   django/branches/newforms-admin/docs/modelforms.txt
   django/branches/newforms-admin/tests/modeltests/model_formsets/models.py
Log:
newforms-admin: Fixed #7230 -- Added a save_m2m method to BaseModelFormSet when 
commit=False is passed to save. Thanks Books Travis for the original report.

Modified: django/branches/newforms-admin/django/newforms/models.py
===================================================================
--- django/branches/newforms-admin/django/newforms/models.py    2008-07-15 
21:43:21 UTC (rev 7929)
+++ django/branches/newforms-admin/django/newforms/models.py    2008-07-15 
22:41:17 UTC (rev 7930)
@@ -331,6 +331,12 @@
         """Saves model instances for every form, adding and changing instances
         as necessary, and returns the list of instances.
         """
+        if not commit:
+            self.saved_forms = []
+            def save_m2m():
+                for form in self.saved_forms:
+                    form.save_m2m()
+            self.save_m2m = save_m2m
         return self.save_existing_objects(commit) + 
self.save_new_objects(commit)
 
     def save_existing_objects(self, commit=True):
@@ -353,6 +359,8 @@
                 if form.changed_data:
                     self.changed_objects.append((obj, form.changed_data))
                     saved_instances.append(self.save_existing(form, obj, 
commit=commit))
+                    if not commit:
+                        self.saved_forms.append(form)
         return saved_instances
 
     def save_new_objects(self, commit=True):
@@ -365,6 +373,8 @@
             if self.can_delete and form.cleaned_data[DELETION_FIELD_NAME]:
                 continue
             self.new_objects.append(self.save_new(form, commit=commit))
+            if not commit:
+                self.saved_forms.append(form)
         return self.new_objects
 
     def add_fields(self, form, index):

Modified: django/branches/newforms-admin/docs/modelforms.txt
===================================================================
--- django/branches/newforms-admin/docs/modelforms.txt  2008-07-15 21:43:21 UTC 
(rev 7929)
+++ django/branches/newforms-admin/docs/modelforms.txt  2008-07-15 22:41:17 UTC 
(rev 7930)
@@ -454,7 +454,9 @@
     ...     instance.save()
 
 This gives you the ability to attach data to the instances before saving them
-to the database.
+to the database. If your formset contains a ``ManyToManyField`` you will also
+need to make a call to ``formset.save_m2m()`` to ensure the many-to-many
+relationships are saved properly.
 
 Limiting the number of objects editable
 ---------------------------------------

Modified: 
django/branches/newforms-admin/tests/modeltests/model_formsets/models.py
===================================================================
--- django/branches/newforms-admin/tests/modeltests/model_formsets/models.py    
2008-07-15 21:43:21 UTC (rev 7929)
+++ django/branches/newforms-admin/tests/modeltests/model_formsets/models.py    
2008-07-15 22:41:17 UTC (rev 7930)
@@ -13,9 +13,19 @@
     def __unicode__(self):
         return self.title
 
+class AuthorMeeting(models.Model):
+    name = models.CharField(max_length=100)
+    authors = models.ManyToManyField(Author)
+    created = models.DateField(editable=False)
+    
+    def __unicode__(self):
+        return self.name
 
+
 __test__ = {'API_TESTS': """
 
+>>> from datetime import date
+
 >>> from django.newforms.models import modelformset_factory
 
 >>> qs = Author.objects.all()
@@ -162,6 +172,40 @@
 >>> formset.save()
 [<Author: Walt Whitman>]
 
+Test the behavior of commit=False and save_m2m
+
+>>> meeting = AuthorMeeting.objects.create(created=date.today())
+>>> meeting.authors = Author.objects.all()
+
+# create an Author instance to add to the meeting.
+>>> new_author = Author.objects.create(name=u'John Steinbeck')
+
+>>> AuthorMeetingFormSet = modelformset_factory(AuthorMeeting, extra=1, 
can_delete=True)
+>>> data = {
+...     'form-TOTAL_FORMS': '2', # the number of forms rendered
+...     'form-INITIAL_FORMS': '1', # the number of forms with initial data
+...     'form-MAX_FORMS': '0', # the max number of forms
+...     'form-0-id': '1',
+...     'form-0-name': '2nd Tuesday of the Week Meeting',
+...     'form-0-authors': [2, 1, 3, 4],
+...     'form-1-name': '',
+...     'form-1-authors': '',
+...     'form-1-DELETE': '',
+... }
+>>> formset = AuthorMeetingFormSet(data=data, 
queryset=AuthorMeeting.objects.all())
+>>> formset.is_valid()
+True
+>>> instances = formset.save(commit=False)
+>>> for instance in instances:
+...     instance.created = date.today()
+...     instance.save()
+>>> formset.save_m2m()
+>>> instances[0].authors.all()
+[<Author: Charles Baudelaire>, <Author: Walt Whitman>, <Author: Paul 
Verlaine>, <Author: John Steinbeck>]
+
+# delete the author we created to allow later tests to continue working.
+>>> new_author.delete()
+
 Test the behavior of max_num with model formsets. It should properly limit
 the queryset to reduce the amount of objects being pulled in when not being
 used.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to