diff --git a/core/admin.py b/core/admin.py index e3832dd7..c74cbd0c 100644 --- a/core/admin.py +++ b/core/admin.py @@ -3,9 +3,10 @@ from contextlib import suppress from constance.admin import Config from constance.admin import ConstanceAdmin as BaseConstanceAdmin from django.apps import apps -from django.contrib.admin import ModelAdmin, TabularInline, action, register, site +from django.contrib.admin import FieldListFilter, ModelAdmin, TabularInline, action, register, site from django.contrib.gis.admin import GISModelAdmin from django.db.models import Model +from django.urls import reverse from django.utils.translation import gettext_lazy as _ from modeltranslation.translator import NotRegistered, translator from modeltranslation.utils import get_translation_fields @@ -36,6 +37,49 @@ from .models import ( ) +class RelatedAutocompleteFilter(FieldListFilter): + template = "admin/autocomplete_list_filter.html" + limit = 10 + + def __init__(self, field, request, params, model, model_admin, field_path): + self.field = field + self.request = request + self.params = params + self.model_admin = model_admin + self.field_path = field_path + + self.lookup_kwarg = f"{field_path}__{field.target_field.name}__exact" + self.lookup_val = params.get(self.lookup_kwarg) + + rel_model = field.remote_field.model + app_label = rel_model._meta.app_label + model_name = rel_model._meta.model_name + url_name = f"admin:{app_label}_{model_name}_autocomplete" + self.autocomplete_url = ( + reverse(url_name) + + f"?field_name={field.name}&limit={self.limit}" + ) + + def expected_parameters(self): + return [self.lookup_kwarg] + + def has_output(self): + return True + + 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": _("—"), + "autocomplete_url": self.autocomplete_url, + "lookup_kwarg": self.lookup_kwarg, + "lookup_val": self.lookup_val or "", + } + + class FieldsetsMixin: general_fields: list = [] relation_fields: list = [] @@ -242,16 +286,14 @@ class ProductAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin): "rating", "modified", ) - autocomplete_list_filter = ( - "category", - "brand", - ) list_filter = ( "is_active", "is_digital", "stocks__vendor", "created", "modified", + ("brand", RelatedAutocompleteFilter), + ("category", RelatedAutocompleteFilter), ) search_fields = ( "name", diff --git a/core/templates/admin/autocomplete_list_filter.html b/core/templates/admin/autocomplete_list_filter.html new file mode 100644 index 00000000..db1d9ce4 --- /dev/null +++ b/core/templates/admin/autocomplete_list_filter.html @@ -0,0 +1,42 @@ +{% load i18n admin_urls static %} +
+ {# A hidden input to carry the selected value #} + + {# The visible text input #} + +
+ + + + + + +