Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#34001 closed Cleanup/optimization (invalid)

ForeignKey.formfield(): allow override for all kwargs

Reported by: James Pic Owned by: nobody
Component: Database layer (models, ORM) Version: 4.0
Severity: Normal Keywords:
Cc: James Pic Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by James Pic)

Proposing to change ForeignKey.formfield() to allow overriding form_class and all other defaults like with other fields such as fields.UUIDField, we can optimize the code at the same time.

commit ec0cae2e2d0bc6ae31cf39e7c4a067810cff8fb4 (HEAD -> main, origin/formfield)
Author: jpic <jpic@yourlabs.org>
Date:   Sat Sep 10 00:47:17 2022 +0200

    ForeignKey.formfield(): set defaults if necessary (allow override)

    Allow to override defaults used by formfield() in ForeignKey subclasses.

diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 63ed2ff4c7..f9c6ff3be8 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -1164,15 +1164,21 @@ class ForeignKey(ForeignObject):
                 "its related model %r has not been loaded yet"
                 % (self.name, self.remote_field.model)
             )
-        return super().formfield(
-            **{
-                "form_class": forms.ModelChoiceField,
-                "queryset": self.remote_field.model._default_manager.using(using),
-                "to_field_name": self.remote_field.field_name,
-                **kwargs,
-                "blank": self.blank,
-            }
-        )
+
+        if "form_class" not in kwargs:
+            kwargs["form_class"] = forms.ModelChoiceField
+
+        if "queryset" not in kwargs:
+            kwargs["queryset"] = self.remote_field.model._default_manager.using(
+                using)
+
+        if "to_field_name" not in kwargs:
+            kwargs["to_field_name"] = self.remote_field.field_name
+
+        if "blank" not in kwargs:
+            kwargs["blank"] = self.blank
+
+        return super().formfield(**kwargs)

Change History (6)

comment:1 by James Pic, 2 years ago

Cc: James Pic added
Component: UncategorizedDatabase layer (models, ORM)
Description: modified (diff)
Type: UncategorizedCleanup/optimization

comment:2 by James Pic, 2 years ago

Description: modified (diff)

comment:3 by Mariusz Felisiak, 2 years ago

Resolution: needsinfo
Status: newclosed

Thanks for the ticket, however I'm a bit confused. Is it not possible? The values from kwargs should override form_class, queryset, and to_field_name in **{..., **kwargs}. The only difference is in blank but in this case we should keep the value from a model field.

comment:4 by James Pic, 2 years ago

You are correct, my bad, should have went to sleep instead :P

comment:5 by James Pic, 2 years ago

Resolution: needsinfofixed

comment:6 by Tim Graham, 2 years ago

Resolution: fixedinvalid
Note: See TracTickets for help on using tickets.
Back to Top