Ticket #16115: new_hook_save_model_and_relations_with_tests_and_docs.diff
File new_hook_save_model_and_relations_with_tests_and_docs.diff, 8.6 KB (added by , 13 years ago) |
---|
-
docs/ref/contrib/admin/index.txt
949 949 instance.save() 950 950 formset.save_m2m() 951 951 952 .. method:: ModelAdmin.save_model_and_relations(self, request, obj, form, formsets, change) 953 954 .. versionadded:: 1.4 955 956 The ``save_model_and_relations`` method is given the ``HttpRequest``, 957 a model instance, a ``ModelForm`` instance, a list of formsets where each one 958 represent and inline group, and boolean value based on whether it is 959 adding or changing the object. 960 961 This method is the last step on ``add_view`` and ``change_view``, where is 962 guaranteed that the object and all related inlines are already saved. 963 952 964 .. method:: ModelAdmin.get_readonly_fields(self, request, obj=None) 953 965 954 966 .. versionadded:: 1.2 -
django/contrib/admin/options.py
683 683 """ 684 684 formset.save() 685 685 686 def save_model_and_relations(self, request, obj, form, formsets, change): 687 """ 688 Given a model instance, a bound form and a list of inline formsets 689 save everything in to the database. 690 691 At this point save_form() has already been called, so just 692 form.save_m2m() needs to be called. 693 """ 694 self.save_model(request, obj, form, change=change) 695 form.save_m2m() 696 for formset in formsets: 697 self.save_formset(request, form, formset, change=change) 698 686 699 def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None): 687 700 opts = self.model._meta 688 701 app_label = opts.app_label … … 886 899 prefix=prefix, queryset=inline.queryset(request)) 887 900 formsets.append(formset) 888 901 if all_valid(formsets) and form_validated: 889 self.save_model(request, new_object, form, change=False) 890 form.save_m2m() 891 for formset in formsets: 892 self.save_formset(request, form, formset, change=False) 902 self.save_model_and_relations(request, new_object, form, formsets, change=False) 893 903 894 904 self.log_addition(request, new_object) 895 905 return self.response_add(request, new_object) … … 988 998 formsets.append(formset) 989 999 990 1000 if all_valid(formsets) and form_validated: 991 self.save_model(request, new_object, form, change=True) 992 form.save_m2m() 993 for formset in formsets: 994 self.save_formset(request, form, formset, change=True) 1001 self.save_model_and_relations(request, new_object, form, formsets, change=True) 995 1002 996 1003 change_message = self.construct_change_message(request, form, formsets) 997 1004 self.log_change(request, new_object, change_message) -
tests/regressiontests/admin_views/tests.py
37 37 Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, 38 38 Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee, 39 39 Question, Answer, Inquisition, Actor, FoodDelivery, 40 RowLevelChangePermissionModel, Paper, CoverLetter, Story, OtherStory) 40 RowLevelChangePermissionModel, Paper, CoverLetter, Story, OtherStory, 41 Parent, Child) 41 42 42 43 43 44 class AdminViewBasicTest(TestCase): … … 3001 3002 self.assert_non_localized_year(response, 2000) 3002 3003 self.assert_non_localized_year(response, 2003) 3003 3004 self.assert_non_localized_year(response, 2005) 3005 3006 class AdminHooksTests(TestCase): 3007 fixtures = ['admin-views-users.xml'] 3008 3009 def setUp(self): 3010 self.client.login(username='super', password='secret') 3011 3012 def test_should_be_able_to_edit_related_objects_on_add_view(self): 3013 post = { 3014 'child_set-TOTAL_FORMS': '3', 3015 'child_set-INITIAL_FORMS': '0', 3016 'name': 'Josh Stone', 3017 'child_set-0-name': 'Paul', 3018 'child_set-1-name': 'Catherine', 3019 } 3020 response = self.client.post('/test_admin/admin/admin_views/parent/add/', post) 3021 self.assertEqual(1, Parent.objects.count()) 3022 self.assertEqual(2, Child.objects.count()) 3023 3024 children_names = list(Child.objects.order_by('name').values_list('name', flat=True)) 3025 3026 self.assertEqual('Josh Stone', Parent.objects.latest('id').name) 3027 self.assertEqual([u'Catherine Stone', u'Paul Stone'], children_names) 3028 3029 def test_should_be_able_to_edit_related_objects_on_change_view(self): 3030 parent = Parent.objects.create(name='Josh Stone') 3031 paul = Child.objects.create(parent=parent, name='Paul') 3032 catherine = Child.objects.create(parent=parent, name='Catherine') 3033 post = { 3034 'child_set-TOTAL_FORMS': '5', 3035 'child_set-INITIAL_FORMS': '2', 3036 'name': 'Josh Stone', 3037 'child_set-0-name': 'Paul', 3038 'child_set-0-id': paul.id, 3039 'child_set-1-name': 'Catherine', 3040 'child_set-1-id': catherine.id, 3041 } 3042 response = self.client.post('/test_admin/admin/admin_views/parent/%s/' % parent.id, post) 3043 3044 children_names = list(Child.objects.order_by('name').values_list('name', flat=True)) 3045 3046 self.assertEqual('Josh Stone', Parent.objects.latest('id').name) 3047 self.assertEqual([u'Catherine Stone', u'Paul Stone'], children_names) 3048 No newline at end of file -
tests/regressiontests/admin_views/models.py
386 386 class ParentAdmin(admin.ModelAdmin): 387 387 model = Parent 388 388 inlines = [ChildInline] 389 390 def save_model_and_relations(self, request, obj, form, formsets, change): 391 super(ParentAdmin, self).save_model_and_relations(request, obj, form, formsets, change) 392 first_name, last_name = obj.name.split() 393 for child in obj.child_set.all(): 394 if len(child.name.split()) < 2: 395 child.name = child.name + ' ' + last_name 396 child.save() 389 397 390 398 class EmptyModel(models.Model): 391 399 def __unicode__(self): -
tests/regressiontests/modeladmin/tests.py
302 302 self.assertEqual( 303 303 list(ma.get_formsets(request))[0]().forms[0].fields.keys(), 304 304 ['extra', 'transport', 'id', 'DELETE', 'main_band']) 305 306 def test_save_model_and_relations_should_call_save_model_and_save_formset(self): 307 method_calls = { 308 'save_model': [], 309 'save_formset': [], 310 'form.save_m2m': False 311 } 312 class BandAdmin(ModelAdmin): 313 def save_model(self, request, obj, form, change): 314 method_calls['save_model'] = (request, obj, form, change) 305 315 316 def save_formset(self, request, form, formset, change): 317 method_calls['save_formset'].append((request, form, formset, change)) 306 318 319 class FakeForm(object): 320 def save_m2m(self): 321 method_calls['form.save_m2m'] = True 322 323 request, obj, form, formset1, formset2 = object(), object, FakeForm(), object(), object() 324 325 band_admin = BandAdmin(Band, self.site) 326 band_admin.save_model_and_relations(request, obj, form, [formset1,formset2], change=True) 327 328 self.assertTrue(1, len(method_calls['save_model'])) 329 self.assertTrue(2, len(method_calls['save_formset'])) 330 self.assertEqual((request, obj, form, True), method_calls['save_model']) 331 self.assertTrue((request, form, formset1, True), method_calls['save_formset'][0]) 332 self.assertTrue((request, form, formset2, True), method_calls['save_formset'][1]) 333 334 307 335 class ValidationTests(unittest.TestCase): 308 336 def test_validation_only_runs_in_debug(self): 309 337 # Ensure validation only runs when DEBUG = True