summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Rosner <brosner@gmail.com>2008-06-10 03:54:05 +0000
committerBrian Rosner <brosner@gmail.com>2008-06-10 03:54:05 +0000
commit3b92ced51856e740cd6fb3d3e5bb8ea932bd276e (patch)
tree6eafa71c49c140116f616cf8b07e0c91bb7aaa67
parentbb75091bf46d9921ecdd89155866e929cc70a38e (diff)
newforms-admin: Fixed #5520 -- Implemented save_as functionality. This also
properly makes inlines work as well. git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7603 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/contrib/admin/options.py4
-rw-r--r--django/contrib/admin/templatetags/admin_modify.py4
-rw-r--r--django/newforms/formsets.py12
-rw-r--r--django/newforms/models.py20
-rw-r--r--tests/modeltests/model_formsets/models.py22
5 files changed, 49 insertions, 13 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index fbd42524ae..c5e3e6232e 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -447,6 +447,7 @@ class ModelAdmin(BaseModelAdmin):
'form_url': mark_safe(form_url),
'opts': opts,
'content_type_id': ContentType.objects.get_for_model(model).id,
+ 'save_as': self.save_as,
'save_on_top': self.save_on_top,
}
context.update(extra_context)
@@ -477,7 +478,8 @@ class ModelAdmin(BaseModelAdmin):
if request.method == 'POST':
form = ModelForm(request.POST, request.FILES)
for FormSet in self.get_formsets(request):
- inline_formset = FormSet(data=request.POST, files=request.FILES, instance=obj)
+ inline_formset = FormSet(data=request.POST, files=request.FILES,
+ instance=obj, save_as_new=request.POST.has_key("_saveasnew"))
inline_formsets.append(inline_formset)
if all_valid(inline_formsets) and form.is_valid():
return self.save_add(request, model, form, inline_formsets, '../%s/')
diff --git a/django/contrib/admin/templatetags/admin_modify.py b/django/contrib/admin/templatetags/admin_modify.py
index ed3768bbc5..3264e89b80 100644
--- a/django/contrib/admin/templatetags/admin_modify.py
+++ b/django/contrib/admin/templatetags/admin_modify.py
@@ -20,9 +20,7 @@ def submit_row(context):
opts = context['opts']
change = context['change']
is_popup = context['is_popup']
- # TODO: Fix this hack.
- # save_as = opts.admin.save_as
- save_as = False
+ save_as = context['save_as']
return {
'onclick_attrib': (opts.get_ordered_objects() and change
and 'onclick="submitOrderForm();"' or ''),
diff --git a/django/newforms/formsets.py b/django/newforms/formsets.py
index b9e4a1fd02..8a76a54042 100644
--- a/django/newforms/formsets.py
+++ b/django/newforms/formsets.py
@@ -57,14 +57,18 @@ class BaseFormSet(StrAndUnicode):
initial = {TOTAL_FORM_COUNT: self._total_form_count, INITIAL_FORM_COUNT: self._initial_form_count}
self.management_form = ManagementForm(initial=initial, auto_id=self.auto_id, prefix=self.prefix)
- # instantiate all the forms and put them in self.forms
- self.forms = []
- for i in range(self._total_form_count):
- self.forms.append(self._construct_form(i))
+ # construct the forms in the formset
+ self._construct_forms()
def __unicode__(self):
return self.as_table()
+ def _construct_forms(self):
+ # instantiate all the forms and put them in self.forms
+ self.forms = []
+ for i in xrange(self._total_form_count):
+ self.forms.append(self._construct_form(i))
+
def _construct_form(self, i):
"""
Instantiates and returns the i-th form instance in a formset.
diff --git a/django/newforms/models.py b/django/newforms/models.py
index 0d946b68b0..b097cd7155 100644
--- a/django/newforms/models.py
+++ b/django/newforms/models.py
@@ -302,11 +302,13 @@ class BaseModelFormSet(BaseFormSet):
"""
model = None
- def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, queryset=None):
+ def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
+ queryset=None, **kwargs):
self.queryset = queryset
- kwargs = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix}
- kwargs['initial'] = [model_to_dict(obj) for obj in self.get_queryset()]
- super(BaseModelFormSet, self).__init__(**kwargs)
+ defaults = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix}
+ defaults['initial'] = [model_to_dict(obj) for obj in self.get_queryset()]
+ defaults.update(kwargs)
+ super(BaseModelFormSet, self).__init__(**defaults)
def get_queryset(self):
if self.queryset is not None:
@@ -386,12 +388,20 @@ def _modelformset_factory(model, form=ModelForm, formfield_callback=lambda f: f.
class BaseInlineFormset(BaseModelFormSet):
"""A formset for child objects related to a parent."""
- def __init__(self, data=None, files=None, instance=None):
+ def __init__(self, data=None, files=None, instance=None, save_as_new=False):
from django.db.models.fields.related import RelatedObject
self.instance = instance
+ self.save_as_new = save_as_new
# is there a better way to get the object descriptor?
self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
super(BaseInlineFormset, self).__init__(data, files, prefix=self.rel_name)
+
+ def _construct_forms(self):
+ from django.newforms.formsets import INITIAL_FORM_COUNT
+ if self.save_as_new:
+ self._total_form_count = self.management_form.cleaned_data[INITIAL_FORM_COUNT]
+ self._initial_form_count = 0
+ super(BaseInlineFormset, self)._construct_forms()
def get_queryset(self):
"""
diff --git a/tests/modeltests/model_formsets/models.py b/tests/modeltests/model_formsets/models.py
index 89a4e0bf5c..9fd50e7521 100644
--- a/tests/modeltests/model_formsets/models.py
+++ b/tests/modeltests/model_formsets/models.py
@@ -232,4 +232,26 @@ As you can see, 'Le Spleen de Paris' is now a book belonging to Charles Baudelai
Le Spleen de Paris
Les Fleurs du Mal
+The save_as_new parameter lets you re-associate the data to a new instance.
+This is used in the admin for save_as functionality.
+
+>>> data = {
+... 'book_set-TOTAL_FORMS': '3', # the number of forms rendered
+... 'book_set-INITIAL_FORMS': '2', # the number of forms with initial data
+... 'book_set-0-id': '1',
+... 'book_set-0-title': 'Les Fleurs du Mal',
+... 'book_set-1-id': '2',
+... 'book_set-1-title': 'Le Spleen de Paris',
+... 'book_set-2-title': '',
+... }
+
+>>> formset = AuthorBooksFormSet(data, instance=Author(), save_as_new=True)
+>>> formset.is_valid()
+True
+
+>>> new_author = Author.objects.create(name='Charles Baudelaire')
+>>> formset.instance = new_author
+>>> [book for book in formset.save() if book.author.pk == new_author.pk]
+[<Book: Les Fleurs du Mal>, <Book: Le Spleen de Paris>]
+
"""}