diff options
author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-04-27 15:26:23 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-27 15:26:23 +0200 |
commit | 720abed34304ec410c04a2e7a7dec7be4dae0d61 (patch) | |
tree | 989349b66b05de9e6c11efbaa1ac8d70d9a9cb53 | |
parent | 23d24f82a7450ef5d369845e18cc0130be5bac6c (diff) | |
download | django-720abed34304ec410c04a2e7a7dec7be4dae0d61.tar.gz |
Avoided creating default form fields in fields_for_model() when declared on form.
-rw-r--r-- | django/forms/models.py | 12 | ||||
-rw-r--r-- | tests/model_forms/tests.py | 9 |
2 files changed, 19 insertions, 2 deletions
diff --git a/django/forms/models.py b/django/forms/models.py index a8e6432f2a..3fa04b821f 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -146,6 +146,7 @@ def fields_for_model( field_classes=None, *, apply_limit_choices_to=True, + form_declared_fields=None, ): """ Return a dictionary containing form fields for the given model. @@ -176,7 +177,11 @@ def fields_for_model( ``apply_limit_choices_to`` is a boolean indicating if limit_choices_to should be applied to a field's queryset. + + ``form_declared_fields`` is a dictionary of form fields created directly on + a form. """ + form_declared_fields = form_declared_fields or {} field_dict = {} ignored = [] opts = model._meta @@ -204,6 +209,9 @@ def fields_for_model( continue if exclude and f.name in exclude: continue + if f.name in form_declared_fields: + field_dict[f.name] = form_declared_fields[f.name] + continue kwargs = {} if widgets and f.name in widgets: @@ -310,6 +318,7 @@ class ModelFormMetaclass(DeclarativeFieldsMetaclass): opts.field_classes, # limit_choices_to will be applied during ModelForm.__init__(). apply_limit_choices_to=False, + form_declared_fields=new_class.declared_fields, ) # make sure opts.fields doesn't specify an invalid field @@ -319,8 +328,7 @@ class ModelFormMetaclass(DeclarativeFieldsMetaclass): message = "Unknown field(s) (%s) specified for %s" message %= (", ".join(missing_fields), opts.model.__name__) raise FieldError(message) - # Override default model fields with any custom declared ones - # (plus, include all the other declared fields). + # Include all the other declared fields. fields.update(new_class.declared_fields) else: fields = new_class.declared_fields diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index 8268032e3c..2295530562 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -236,6 +236,15 @@ class ModelFormBaseTest(TestCase): field_dict = fields_for_model(Person, fields=()) self.assertEqual(len(field_dict), 0) + def test_fields_for_model_form_fields(self): + form_declared_fields = CustomWriterForm.declared_fields + field_dict = fields_for_model( + Writer, + fields=["name"], + form_declared_fields=form_declared_fields, + ) + self.assertIs(field_dict["name"], form_declared_fields["name"]) + def test_empty_fields_on_modelform(self): """ No fields on a ModelForm should actually result in no fields. |