Kaydet (Commit) 332a4855 authored tarafından Jannis Leidel's avatar Jannis Leidel

Fixed #16115 -- Added ModelAdmin.save_related method to be able to do pre- or…

Fixed #16115 -- Added ModelAdmin.save_related method to be able to do pre- or post-save operations for objects related to the parent object currently displayed. Thanks, Julien Phalip.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16498 bcc190cf-cafb-0310-a4f2-bffc1f526a37
üst f9fe112f
......@@ -696,6 +696,18 @@ class ModelAdmin(BaseModelAdmin):
"""
formset.save()
def save_related(self, request, form, formsets, change):
"""
Given the ``HttpRequest``, the parent ``ModelForm`` instance, the
list of inline formsets and a boolean value based on whether the
parent is being added or changed, save the related objects to the
database. Note that at this point save_form() and save_model() have
already been called.
"""
form.save_m2m()
for formset in formsets:
self.save_formset(request, form, formset, change=change)
def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
opts = self.model._meta
app_label = opts.app_label
......@@ -899,11 +911,8 @@ class ModelAdmin(BaseModelAdmin):
prefix=prefix, queryset=inline.queryset(request))
formsets.append(formset)
if all_valid(formsets) and form_validated:
self.save_model(request, new_object, form, change=False)
form.save_m2m()
for formset in formsets:
self.save_formset(request, form, formset, change=False)
self.save_model(request, new_object, form, False)
self.save_related(request, form, formsets, False)
self.log_addition(request, new_object)
return self.response_add(request, new_object)
else:
......@@ -1001,11 +1010,8 @@ class ModelAdmin(BaseModelAdmin):
formsets.append(formset)
if all_valid(formsets) and form_validated:
self.save_model(request, new_object, form, change=True)
form.save_m2m()
for formset in formsets:
self.save_formset(request, form, formset, change=True)
self.save_model(request, new_object, form, True)
self.save_related(request, form, formsets, True)
change_message = self.construct_change_message(request, form, formsets)
self.log_change(request, new_object, change_message)
return self.response_change(request, new_object)
......
......@@ -978,6 +978,16 @@ templates used by the :class:`ModelAdmin` views:
else:
return ['name']
.. method:: ModelAdmin.save_related(self, request, form, formsets, change)
.. versionadded:: 1.4
The ``save_related`` method is given the ``HttpRequest``, the parent
``ModelForm`` instance, the list of inline formsets and a boolean value
based on whether the parent is being added or changed. Here you can do any
pre- or post-save operations for objects related to the parent. Note
that at this point the parent object and its form have already been saved.
.. method:: ModelAdmin.get_readonly_fields(self, request, obj=None)
.. versionadded:: 1.2
......
......@@ -80,6 +80,13 @@ to work similarly to how desktop GUIs do it. The new hook
:meth:`~django.contrib.admin.ModelAdmin.get_ordering` for specifying the
ordering dynamically (e.g. depending on the request) has also been added.
``ModelAdmin.save_related()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A new :meth:`~django.contrib.admin.ModelAdmin.save_related` hook was added to
:mod:`~django.contrib.admin.ModelAdmin` to ease the customization of how
related objects are saved in the admin.
Tools for cryptographic signing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
......@@ -391,6 +391,14 @@ class ParentAdmin(admin.ModelAdmin):
model = Parent
inlines = [ChildInline]
def save_related(self, request, form, formsets, change):
super(ParentAdmin, self).save_related(request, form, formsets, change)
first_name, last_name = form.instance.name.split()
for child in form.instance.child_set.all():
if len(child.name.split()) < 2:
child.name = child.name + ' ' + last_name
child.save()
class EmptyModel(models.Model):
def __unicode__(self):
return "Primary key = %s" % self.id
......
......@@ -38,7 +38,7 @@ from models import (Article, BarAccount, CustomArticle, EmptyModel,
Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee,
Question, Answer, Inquisition, Actor, FoodDelivery,
RowLevelChangePermissionModel, Paper, CoverLetter, Story, OtherStory,
ComplexSortedPerson)
ComplexSortedPerson, Parent, Child)
class AdminViewBasicTest(TestCase):
......@@ -3113,3 +3113,50 @@ class DateHierarchyTests(TestCase):
self.assert_non_localized_year(response, 2000)
self.assert_non_localized_year(response, 2003)
self.assert_non_localized_year(response, 2005)
class AdminCustomSaveRelatedTests(TestCase):
"""
Ensure that one can easily customize the way related objects are saved.
Refs #16115.
"""
fixtures = ['admin-views-users.xml']
def setUp(self):
self.client.login(username='super', password='secret')
def test_should_be_able_to_edit_related_objects_on_add_view(self):
post = {
'child_set-TOTAL_FORMS': '3',
'child_set-INITIAL_FORMS': '0',
'name': 'Josh Stone',
'child_set-0-name': 'Paul',
'child_set-1-name': 'Catherine',
}
response = self.client.post('/test_admin/admin/admin_views/parent/add/', post)
self.assertEqual(1, Parent.objects.count())
self.assertEqual(2, Child.objects.count())
children_names = list(Child.objects.order_by('name').values_list('name', flat=True))
self.assertEqual('Josh Stone', Parent.objects.latest('id').name)
self.assertEqual([u'Catherine Stone', u'Paul Stone'], children_names)
def test_should_be_able_to_edit_related_objects_on_change_view(self):
parent = Parent.objects.create(name='Josh Stone')
paul = Child.objects.create(parent=parent, name='Paul')
catherine = Child.objects.create(parent=parent, name='Catherine')
post = {
'child_set-TOTAL_FORMS': '5',
'child_set-INITIAL_FORMS': '2',
'name': 'Josh Stone',
'child_set-0-name': 'Paul',
'child_set-0-id': paul.id,
'child_set-1-name': 'Catherine',
'child_set-1-id': catherine.id,
}
response = self.client.post('/test_admin/admin/admin_views/parent/%s/' % parent.id, post)
children_names = list(Child.objects.order_by('name').values_list('name', flat=True))
self.assertEqual('Josh Stone', Parent.objects.latest('id').name)
self.assertEqual([u'Catherine Stone', u'Paul Stone'], children_names)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment