1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

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.

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7930 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Brian Rosner 2008-07-15 22:41:17 +00:00
parent a2c7bfc1be
commit 55744e997f
3 changed files with 57 additions and 1 deletions

View File

@ -331,6 +331,12 @@ class BaseModelFormSet(BaseFormSet):
"""Saves model instances for every form, adding and changing instances """Saves model instances for every form, adding and changing instances
as necessary, and returns the list of 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) return self.save_existing_objects(commit) + self.save_new_objects(commit)
def save_existing_objects(self, commit=True): def save_existing_objects(self, commit=True):
@ -353,6 +359,8 @@ class BaseModelFormSet(BaseFormSet):
if form.changed_data: if form.changed_data:
self.changed_objects.append((obj, form.changed_data)) self.changed_objects.append((obj, form.changed_data))
saved_instances.append(self.save_existing(form, obj, commit=commit)) saved_instances.append(self.save_existing(form, obj, commit=commit))
if not commit:
self.saved_forms.append(form)
return saved_instances return saved_instances
def save_new_objects(self, commit=True): def save_new_objects(self, commit=True):
@ -365,6 +373,8 @@ class BaseModelFormSet(BaseFormSet):
if self.can_delete and form.cleaned_data[DELETION_FIELD_NAME]: if self.can_delete and form.cleaned_data[DELETION_FIELD_NAME]:
continue continue
self.new_objects.append(self.save_new(form, commit=commit)) self.new_objects.append(self.save_new(form, commit=commit))
if not commit:
self.saved_forms.append(form)
return self.new_objects return self.new_objects
def add_fields(self, form, index): def add_fields(self, form, index):

View File

@ -454,7 +454,9 @@ model instances without any database interaction::
... instance.save() ... instance.save()
This gives you the ability to attach data to the instances before saving them 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 Limiting the number of objects editable
--------------------------------------- ---------------------------------------

View File

@ -13,9 +13,19 @@ class Book(models.Model):
def __unicode__(self): def __unicode__(self):
return self.title 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': """ __test__ = {'API_TESTS': """
>>> from datetime import date
>>> from django.newforms.models import modelformset_factory >>> from django.newforms.models import modelformset_factory
>>> qs = Author.objects.all() >>> qs = Author.objects.all()
@ -162,6 +172,40 @@ True
>>> formset.save() >>> formset.save()
[<Author: Walt Whitman>] [<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 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 the queryset to reduce the amount of objects being pulled in when not being
used. used.