From 92cb2aeab3b80c59e712c0d83f106f3e9d32bce6 Mon Sep 17 00:00:00 2001 From: lukas Date: Thu, 30 May 2024 17:50:41 +0200 Subject: [PATCH] fix: raw id fields --- src/unfold/admin.py | 7 ++++++- .../unfold/widgets/foreign_key_raw_id.html | 21 +++++++++++++++++++ src/unfold/widgets.py | 20 ++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/unfold/templates/unfold/widgets/foreign_key_raw_id.html diff --git a/src/unfold/admin.py b/src/unfold/admin.py index a09391a37..b1fdbd939 100644 --- a/src/unfold/admin.py +++ b/src/unfold/admin.py @@ -71,6 +71,7 @@ UnfoldAdminUUIDInputWidget, UnfoldBooleanSwitchWidget, UnfoldBooleanWidget, + UnfoldForeignKeyRawIdWidget, ) try: @@ -306,10 +307,14 @@ def formfield_for_choice_field( def formfield_for_foreignkey( self, db_field: ForeignKey, request: HttpRequest, **kwargs ) -> Optional[ModelChoiceField]: + db = kwargs.get("using") + # Overrides widgets for all related fields if "widget" not in kwargs: if db_field.name in self.raw_id_fields: - kwargs["widget"] = UnfoldAdminTextInputWidget() + kwargs["widget"] = UnfoldForeignKeyRawIdWidget( + db_field.remote_field, self.admin_site, using=db + ) elif ( db_field.name not in self.get_autocomplete_fields(request) and db_field.name not in self.radio_fields diff --git a/src/unfold/templates/unfold/widgets/foreign_key_raw_id.html b/src/unfold/templates/unfold/widgets/foreign_key_raw_id.html new file mode 100644 index 000000000..33f18abf2 --- /dev/null +++ b/src/unfold/templates/unfold/widgets/foreign_key_raw_id.html @@ -0,0 +1,21 @@ +
+ {% include 'django/forms/widgets/input.html' %} + + {% if related_url %} + + search + + {% endif %} +
+ +{% if link_label %} + + {% if link_url %} + + {{ link_label }} + + {% else %} + {{ link_label }} + {% endif %} + +{% endif %} diff --git a/src/unfold/widgets.py b/src/unfold/widgets.py index 63c01d1d5..711802939 100644 --- a/src/unfold/widgets.py +++ b/src/unfold/widgets.py @@ -1,6 +1,7 @@ from typing import Any, Callable, Dict, Optional, Tuple, Union from django.contrib.admin.options import VERTICAL +from django.contrib.admin.sites import AdminSite from django.contrib.admin.widgets import ( AdminBigIntegerFieldWidget, AdminDateWidget, @@ -13,8 +14,10 @@ AdminTextInputWidget, AdminTimeWidget, AdminUUIDInputWidget, + ForeignKeyRawIdWidget, RelatedFieldWidgetWrapper, ) +from django.db.models.fields.reverse_related import ForeignObjectRel from django.forms import ( CheckboxInput, MultiWidget, @@ -532,3 +535,20 @@ def __init__( class UnfoldRelatedFieldWidgetWrapper(RelatedFieldWidgetWrapper): template_name = "unfold/widgets/related_widget_wrapper.html" + + +class UnfoldForeignKeyRawIdWidget(ForeignKeyRawIdWidget): + template_name = "unfold/widgets/foreign_key_raw_id.html" + + def __init__( + self, + rel: ForeignObjectRel, + admin_site: AdminSite, + attrs: Optional[Dict] = None, + using: Optional[Any] = None, + ) -> None: + attrs = { + "class": " ".join(["vForeignKeyRawIdAdminField"] + INPUT_CLASSES), + **(attrs or {}), + } + return super().__init__(rel, admin_site, attrs, using)