Ticket #16115: new_hook_save_model_and_related_with_tests.diff

File new_hook_save_model_and_related_with_tests.diff, 7.6 KB (added by Igor Sobreira, 6 years ago)
  • tests/regressiontests/admin_views/tests.py

     
    3737    Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
    3838    Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee,
    3939    Question, Answer, Inquisition, Actor, FoodDelivery,
    40     RowLevelChangePermissionModel, Paper, CoverLetter, Story, OtherStory)
     40    RowLevelChangePermissionModel, Paper, CoverLetter, Story, OtherStory,
     41    Parent, Child)
    4142
    4243
    4344class AdminViewBasicTest(TestCase):
     
    30013002            self.assert_non_localized_year(response, 2000)
    30023003            self.assert_non_localized_year(response, 2003)
    30033004            self.assert_non_localized_year(response, 2005)
     3005
     3006class 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

     
    386386class ParentAdmin(admin.ModelAdmin):
    387387    model = Parent
    388388    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()
    389397
    390398class EmptyModel(models.Model):
    391399    def __unicode__(self):
  • tests/regressiontests/modeladmin/tests.py

     
    302302        self.assertEqual(
    303303            list(ma.get_formsets(request))[0]().forms[0].fields.keys(),
    304304            ['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)
    305315
     316            def save_formset(self, request, form, formset, change):
     317                method_calls['save_formset'].append((request, form, formset, change))
    306318
     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
    307335class ValidationTests(unittest.TestCase):
    308336    def test_validation_only_runs_in_debug(self):
    309337        # Ensure validation only runs when DEBUG = True
  • django/contrib/admin/options.py

     
    683683        """
    684684        formset.save()
    685685
     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
    686699    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    687700        opts = self.model._meta
    688701        app_label = opts.app_label
     
    886899                                  prefix=prefix, queryset=inline.queryset(request))
    887900                formsets.append(formset)
    888901            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)
    893903
    894904                self.log_addition(request, new_object)
    895905                return self.response_add(request, new_object)
     
    988998                formsets.append(formset)
    989999
    9901000            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)
    9951002
    9961003                change_message = self.construct_change_message(request, form, formsets)
    9971004                self.log_change(request, new_object, change_message)
Back to Top