Ticket #17683: ticket-17683-basemodelformset-pk-widget-v1.diff

File ticket-17683-basemodelformset-pk-widget-v1.diff, 3.2 KB (added by charettes, 3 years ago)

Fix with tests

  • django/forms/models.py

    diff --git a/django/forms/models.py b/django/forms/models.py
    index cd8f027..d504945 100644
    a b def pk_is_not_editable(pk): 
    658658            else:
    659659                qs = self.model._default_manager.get_query_set()
    660660            qs = qs.using(form.instance._state.db)
    661             form.fields[self._pk_field.name] = ModelChoiceField(qs, initial=pk_value, required=False, widget=HiddenInput)
     661            if form._meta.widgets:
     662                widget = form._meta.widgets.get(self._pk_field.name, HiddenInput)
     663            else:
     664                widget = HiddenInput
     665            form.fields[self._pk_field.name] = ModelChoiceField(qs, initial=pk_value, required=False, widget=widget)
    662666        super(BaseModelFormSet, self).add_fields(form, index)
    663667
    664668def modelformset_factory(model, form=ModelForm, formfield_callback=None,
  • tests/regressiontests/model_formsets_regress/tests.py

    diff --git a/tests/regressiontests/model_formsets_regress/tests.py b/tests/regressiontests/model_formsets_regress/tests.py
    index d058f1d..50fac3c 100644
    a b def test_extraneous_query_is_not_run(self): 
    260260            formset.save()
    261261
    262262
    263 class CustomWidget(forms.CharField):
     263class CustomWidget(forms.widgets.TextInput):
    264264    pass
    265265
    266266
    267267class UserSiteForm(forms.ModelForm):
    268268    class Meta:
    269269        model = UserSite
    270         widgets = {'data': CustomWidget}
     270        widgets = {
     271            'id': CustomWidget,
     272            'data': CustomWidget,
     273        }
    271274
    272275
    273276class Callback(object):
    def __call__(self, db_field, **kwargs): 
    282285
    283286class FormfieldCallbackTests(TestCase):
    284287    """
    285     Regression for #13095: Using base forms with widgets
    286     defined in Meta should not raise errors.
     288    Regression for #13095 and #17683: Using base forms with widgets
     289    defined in Meta should not raise errors and BaseModelForm should respect
     290    the specified pk widget.
    287291    """
    288292
    289293    def test_inlineformset_factory_default(self):
    290294        Formset = inlineformset_factory(User, UserSite, form=UserSiteForm)
    291295        form = Formset().forms[0]
     296        self.assertTrue(isinstance(form['id'].field.widget, CustomWidget))
    292297        self.assertTrue(isinstance(form['data'].field.widget, CustomWidget))
    293298
    294299    def test_modelformset_factory_default(self):
    295300        Formset = modelformset_factory(UserSite, form=UserSiteForm)
    296301        form = Formset().forms[0]
     302        self.assertTrue(isinstance(form['id'].field.widget, CustomWidget))
    297303        self.assertTrue(isinstance(form['data'].field.widget, CustomWidget))
    298304
    299305    def assertCallbackCalled(self, callback):
    300306        id_field, user_field, data_field = UserSite._meta.fields
    301307        expected_log = [
    302             (id_field, {}),
     308            (id_field, {'widget': CustomWidget}),
    303309            (user_field, {}),
    304310            (data_field, {'widget': CustomWidget}),
    305311        ]
    def test_modelformset_custom_callback(self): 
    317323                             formfield_callback=callback)
    318324        self.assertCallbackCalled(callback)
    319325
    320 
    321326class BaseCustomDeleteFormSet(BaseFormSet):
    322327    """
    323328    A formset mix-in that lets a form decide if it's to be deleted.
Back to Top