diff --git a/django/forms/models.py b/django/forms/models.py
index cd8f027..d504945 100644
a
|
b
|
def pk_is_not_editable(pk):
|
658 | 658 | else: |
659 | 659 | qs = self.model._default_manager.get_query_set() |
660 | 660 | 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) |
662 | 666 | super(BaseModelFormSet, self).add_fields(form, index) |
663 | 667 | |
664 | 668 | def modelformset_factory(model, form=ModelForm, formfield_callback=None, |
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):
|
260 | 260 | formset.save() |
261 | 261 | |
262 | 262 | |
263 | | class CustomWidget(forms.CharField): |
| 263 | class CustomWidget(forms.widgets.TextInput): |
264 | 264 | pass |
265 | 265 | |
266 | 266 | |
267 | 267 | class UserSiteForm(forms.ModelForm): |
268 | 268 | class Meta: |
269 | 269 | model = UserSite |
270 | | widgets = {'data': CustomWidget} |
| 270 | widgets = { |
| 271 | 'id': CustomWidget, |
| 272 | 'data': CustomWidget, |
| 273 | } |
271 | 274 | |
272 | 275 | |
273 | 276 | class Callback(object): |
… |
… |
def __call__(self, db_field, **kwargs):
|
282 | 285 | |
283 | 286 | class FormfieldCallbackTests(TestCase): |
284 | 287 | """ |
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. |
287 | 291 | """ |
288 | 292 | |
289 | 293 | def test_inlineformset_factory_default(self): |
290 | 294 | Formset = inlineformset_factory(User, UserSite, form=UserSiteForm) |
291 | 295 | form = Formset().forms[0] |
| 296 | self.assertTrue(isinstance(form['id'].field.widget, CustomWidget)) |
292 | 297 | self.assertTrue(isinstance(form['data'].field.widget, CustomWidget)) |
293 | 298 | |
294 | 299 | def test_modelformset_factory_default(self): |
295 | 300 | Formset = modelformset_factory(UserSite, form=UserSiteForm) |
296 | 301 | form = Formset().forms[0] |
| 302 | self.assertTrue(isinstance(form['id'].field.widget, CustomWidget)) |
297 | 303 | self.assertTrue(isinstance(form['data'].field.widget, CustomWidget)) |
298 | 304 | |
299 | 305 | def assertCallbackCalled(self, callback): |
300 | 306 | id_field, user_field, data_field = UserSite._meta.fields |
301 | 307 | expected_log = [ |
302 | | (id_field, {}), |
| 308 | (id_field, {'widget': CustomWidget}), |
303 | 309 | (user_field, {}), |
304 | 310 | (data_field, {'widget': CustomWidget}), |
305 | 311 | ] |
… |
… |
def test_modelformset_custom_callback(self):
|
317 | 323 | formfield_callback=callback) |
318 | 324 | self.assertCallbackCalled(callback) |
319 | 325 | |
320 | | |
321 | 326 | class BaseCustomDeleteFormSet(BaseFormSet): |
322 | 327 | """ |
323 | 328 | A formset mix-in that lets a form decide if it's to be deleted. |