From 306f54b4a2b0327bb384aec0425176ffd735ea76 Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Tue, 1 Jul 2025 18:35:01 +0300 Subject: [PATCH] Features: 1) Replace autocomplete input with Select2-based dropdown for enhanced functionality and improved styling; 2) Add support for displaying the initial selection text in the dropdown; 3) Load additional Select2-specific JavaScript and CSS resources dynamically; Fixes: 1) Correct handling of initial selection when lookup value is invalid or missing; Extra: 1) Refactor related admin template and Python code to improve readability and maintainability; 2) Align variable names and code style for consistency. --- core/admin.py | 44 +++++++++----- .../admin/autocomplete_list_filter.html | 57 +++++++------------ 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/core/admin.py b/core/admin.py index efd40599..fbafbf5d 100644 --- a/core/admin.py +++ b/core/admin.py @@ -44,20 +44,32 @@ class RelatedAutocompleteFilter(FieldListFilter): def __init__(self, field, request, params, model, model_admin, field_path): super().__init__(field, request, params, model, model_admin, field_path) self.lookup_kwarg = f"{field_path}__{field.target_field.name}__exact" - self.lookup_val = params.get(self.lookup_kwarg, "") + self.lookup_val = params.get(self.lookup_kwarg, "") + remote = field.remote_field.model._meta + self.app_label = remote.app_label + self.model_name = remote.model_name + self.field_name = field.name self.field_label = field.verbose_name - remote_opts = field.remote_field.model._meta base = reverse("admin:autocomplete") self.autocomplete_url = ( f"{base}" - f"?app_label={remote_opts.app_label}" - f"&model_name={remote_opts.model_name}" - f"&field_name={field.name}" + f"?app_label={self.app_label}" + f"&model_name={self.model_name}" + f"&field_name={self.field_name}" f"&limit={self.limit}" ) + if self.lookup_val: + try: + obj = field.remote_field.model._default_manager.get(pk=self.lookup_val) + self.initial_text = str(obj) + except field.remote_field.model.DoesNotExist: + self.initial_text = "" + else: + self.initial_text = "" + def expected_parameters(self): key = f"{self.field_path}__{self.field.target_field.name}__exact" return [key] @@ -67,15 +79,21 @@ class RelatedAutocompleteFilter(FieldListFilter): def choices(self, changelist): yield { - "selected": bool(self.lookup_val), - "query_string": changelist.get_query_string( - ({self.lookup_kwarg: self.lookup_val} if self.lookup_val else {}), [] - ), - "display": _("—"), + "selected": bool(self.lookup_val), + "query_string": changelist.get_query_string( + ({self.lookup_kwarg: self.lookup_val} + if self.lookup_val else {}), + [] + ), + "display": _("—"), "autocomplete_url": self.autocomplete_url, - "lookup_kwarg": self.lookup_kwarg, - "lookup_val": self.lookup_val, - "field_label": self.field_label, + "lookup_kwarg": self.lookup_kwarg, + "lookup_val": self.lookup_val, + "app_label": self.app_label, + "model_name": self.model_name, + "field_name": self.field_name, + "field_label": self.field_label, + "initial_text": self.initial_text, } diff --git a/core/templates/admin/autocomplete_list_filter.html b/core/templates/admin/autocomplete_list_filter.html index c48f4ede..c61643c3 100644 --- a/core/templates/admin/autocomplete_list_filter.html +++ b/core/templates/admin/autocomplete_list_filter.html @@ -1,40 +1,27 @@ {% load i18n static %}
- - - +
+ + + - - + + +