Features: 1) Remove custom AjaxAutocompleteListFilter and its related widget/templates to streamline admin functionality; 2) Simplify ProductAdmin by using default ModelAdmin.

Fixes: 1) Remove unnecessary imports related to the deleted functionality.

Extra: 1) Extensive cleanup to remove redundant code and references; 2) Minor formatting adjustments for improved readability.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-07-01 17:44:20 +03:00
parent 9a31be98ad
commit a63aa0371a
2 changed files with 2 additions and 98 deletions

View file

@ -3,12 +3,9 @@ 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, RelatedFieldListFilter, TabularInline, action, register, site
from django.contrib.admin.widgets import AutocompleteSelect
from django.contrib.admin import ModelAdmin, TabularInline, action, register, site
from django.contrib.gis.admin import GISModelAdmin
from django.db.models import Model
from django.db.models.fields.related_descriptors import ManyToManyDescriptor, ReverseManyToOneDescriptor
from django.forms import CharField, Form, HiddenInput, ModelChoiceField
from django.utils.translation import gettext_lazy as _
from modeltranslation.translator import NotRegistered, translator
from modeltranslation.utils import get_translation_fields
@ -115,90 +112,6 @@ class ActivationActionsMixin:
return actions
class AjaxAutocompleteSelectWidget(AutocompleteSelect):
def __init__(self, *args, **kwargs):
self.qs_target_value = kwargs.pop("qs_target_value")
self.model_admin = kwargs.pop("model_admin")
self.model = kwargs.pop("model")
self.field_name = kwargs.pop("field_name")
kwargs.update(admin_site=self.model_admin.admin_site)
kwargs.update(field=getattr(self.model, self.field_name).field)
super().__init__(*args, **kwargs)
def render(self, name, value, attrs=None, renderer=None):
rendered = super().render(name, value, attrs, renderer)
return (
f'<div class="ajax-autocomplete-select-widget-wrapper" data-qs-target-value="{self.qs_target_value}">'
f"{rendered}</div>"
)
class AjaxAutocompleteListFilter(RelatedFieldListFilter):
title = _("list filter")
parameter_name = "%s__%s__exact"
template = "admin/filter/autocomplete_list_filter.html"
def __init__(self, field, request, params, model, model_admin, field_path):
super().__init__(field, request, params, model, model_admin, field_path)
qs_target_value = self.parameter_name % (field.name, model._meta.pk.name)
queryset = self.get_queryset_for_field(model, field.name)
widget = AjaxAutocompleteSelectWidget(
model_admin=model_admin, model=model, field_name=field.name, qs_target_value=qs_target_value
)
class AutocompleteForm(Form):
autocomplete_field = ModelChoiceField(queryset=queryset, widget=widget, required=False)
querystring_value = CharField(widget=HiddenInput())
autocomplete_field_initial_value = request.GET.get(qs_target_value, None)
initial_values = {"querystring_value": request.GET.urlencode()}
if autocomplete_field_initial_value:
initial_values.update(autocomplete_field=autocomplete_field_initial_value)
self.autocomplete_form = AutocompleteForm(initial=initial_values, prefix=field.name)
def get_queryset_for_field(self, model, name):
field_desc = getattr(model, name)
if isinstance(field_desc, ManyToManyDescriptor):
related_model = field_desc.rel.related_model if field_desc.reverse else field_desc.rel.model
elif isinstance(field_desc, ReverseManyToOneDescriptor):
related_model = field_desc.rel.related_model
else:
return field_desc.get_queryset()
return related_model.objects.get_queryset()
class AjaxAutocompleteListFilterModelAdmin(ModelAdmin):
def get_list_filter(self, request):
list_filter = list(super().get_list_filter(request))
autocomplete_list_filter = self.get_autocomplete_list_filter()
if autocomplete_list_filter:
for field in autocomplete_list_filter:
list_filter.insert(0, (field, AjaxAutocompleteListFilter))
return list_filter
def get_autocomplete_list_filter(self):
return list(getattr(self, "autocomplete_list_filter", []))
class Media:
js = [
"admin/js/vendor/jquery/jquery.js",
"admin/js/vendor/select2/select2.full.js",
"admin/js/vendor/select2/i18n/tr.js",
"admin/js/jquery.init.js",
"admin/js/autocomplete.js",
"admin/js/autocomplete_list_filter.js",
]
css = {
"screen": [
"admin/css/vendor/select2/select2.css",
"admin/css/autocomplete.css",
"admin/css/autocomplete_list_filter.css",
]
}
class AttributeValueInline(TabularInline):
model = AttributeValue
extra = 0
@ -317,7 +230,7 @@ class BrandAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
@register(Product)
class ProductAdmin(FieldsetsMixin, ActivationActionsMixin, AjaxAutocompleteListFilterModelAdmin):
class ProductAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
model = Product # type: ignore
list_display = (
"name",

View file

@ -1,9 +0,0 @@
{% load i18n static %}
<h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3>
<form method="get">
<ul>
<li>{{ spec.autocomplete_form.autocomplete_field }}</li>
</ul>
{{ spec.autocomplete_form.querystring_value }}
</form>