Features: 1) Add autocomplete_list_filter support in Admin classes; 2) Introduce SkipVariableDoesNotExistFilter to suppress specific log warnings.

Fixes: 1) Clean up unused imports in `filters.py`.

Extra: 1) Apply consistent string quoting across `admin.py` for formatting standardization; 2) Update logging configuration for `django.template` with new filter.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-07-01 16:41:20 +03:00
parent c5fe0cb6c6
commit 1024760c15
3 changed files with 48 additions and 23 deletions

View file

@ -117,10 +117,10 @@ class ActivationActionsMixin:
class AjaxAutocompleteSelectWidget(AutocompleteSelect): class AjaxAutocompleteSelectWidget(AutocompleteSelect):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.qs_target_value = kwargs.pop('qs_target_value') self.qs_target_value = kwargs.pop("qs_target_value")
self.model_admin = kwargs.pop('model_admin') self.model_admin = kwargs.pop("model_admin")
self.model = kwargs.pop('model') self.model = kwargs.pop("model")
self.field_name = kwargs.pop('field_name') self.field_name = kwargs.pop("field_name")
kwargs.update(admin_site=self.model_admin.admin_site) kwargs.update(admin_site=self.model_admin.admin_site)
kwargs.update(field=getattr(self.model, self.field_name).field) kwargs.update(field=getattr(self.model, self.field_name).field)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -128,14 +128,16 @@ class AjaxAutocompleteSelectWidget(AutocompleteSelect):
def render(self, name, value, attrs=None, renderer=None): def render(self, name, value, attrs=None, renderer=None):
rendered = super().render(name, value, attrs, renderer) rendered = super().render(name, value, attrs, renderer)
return (f'<div class="ajax-autocomplete-select-widget-wrapper" data-qs-target-value="{self.qs_target_value}">' return (
f'{rendered}</div>') f'<div class="ajax-autocomplete-select-widget-wrapper" data-qs-target-value="{self.qs_target_value}">'
f"{rendered}</div>"
)
class AjaxAutocompleteListFilter(RelatedFieldListFilter): class AjaxAutocompleteListFilter(RelatedFieldListFilter):
title = _('list filter') title = _("list filter")
parameter_name = '%s__%s__exact' parameter_name = "%s__%s__exact"
template = 'djaa_list_filter/admin/filter/autocomplete_list_filter.html' template = "djaa_list_filter/admin/filter/autocomplete_list_filter.html"
def __init__(self, field, request, params, model, model_admin, field_path): def __init__(self, field, request, params, model, model_admin, field_path):
super().__init__(field, request, params, model, model_admin, field_path) super().__init__(field, request, params, model, model_admin, field_path)
@ -177,22 +179,22 @@ class AjaxAutocompleteListFilterModelAdmin(ModelAdmin):
return list_filter return list_filter
def get_autocomplete_list_filter(self): def get_autocomplete_list_filter(self):
return list(getattr(self, 'autocomplete_list_filter', [])) return list(getattr(self, "autocomplete_list_filter", []))
class Media: class Media:
js = [ js = [
'admin/js/vendor/jquery/jquery.js', "admin/js/vendor/jquery/jquery.js",
'admin/js/vendor/select2/select2.full.js', "admin/js/vendor/select2/select2.full.js",
'admin/js/vendor/select2/i18n/tr.js', "admin/js/vendor/select2/i18n/tr.js",
'admin/js/jquery.init.js', "admin/js/jquery.init.js",
'admin/js/autocomplete.js', "admin/js/autocomplete.js",
'djaa_list_filter/admin/js/autocomplete_list_filter.js', "djaa_list_filter/admin/js/autocomplete_list_filter.js",
] ]
css = { css = {
'screen': [ "screen": [
'admin/css/vendor/select2/select2.css', "admin/css/vendor/select2/select2.css",
'admin/css/autocomplete.css', "admin/css/autocomplete.css",
'djaa_list_filter/admin/css/autocomplete_list_filter.css', "djaa_list_filter/admin/css/autocomplete_list_filter.css",
] ]
} }
@ -327,6 +329,10 @@ class ProductAdmin(FieldsetsMixin, ActivationActionsMixin, AjaxAutocompleteListF
"rating", "rating",
"modified", "modified",
) )
autocomplete_list_filter = (
"category",
"brand",
)
list_filter = ( list_filter = (
"is_active", "is_active",
"is_digital", "is_digital",

View file

@ -2,7 +2,6 @@ import json
import logging import logging
import uuid import uuid
from django.contrib.admin import SimpleListFilter
from django.core.exceptions import BadRequest from django.core.exceptions import BadRequest
from django.db.models import ( from django.db.models import (
Avg, Avg,
@ -17,9 +16,7 @@ from django.db.models import (
When, When,
) )
from django.db.models.functions import Coalesce from django.db.models.functions import Coalesce
from django.urls import reverse
from django.utils.http import urlsafe_base64_decode from django.utils.http import urlsafe_base64_decode
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django_filters import ( from django_filters import (
BaseInFilter, BaseInFilter,

View file

@ -1,5 +1,18 @@
from evibes.settings.base import * # noqa: F403 from evibes.settings.base import * # noqa: F403
class SkipVariableDoesNotExistFilter(logging.Filter): # noqa: F405
def filter(self, record: logging.LogRecord) -> bool: # noqa: F405
if record.exc_info:
exc_type, exc_instance, _ = record.exc_info
try:
if exc_type.__name__ == "VariableDoesNotExist": # type: ignore
return False
except AttributeError:
return True
return "VariableDoesNotExist" not in record.getMessage()
LOGGING = { LOGGING = {
"version": 1, "version": 1,
"disable_existing_loggers": False, "disable_existing_loggers": False,
@ -25,6 +38,9 @@ LOGGING = {
"require_debug_true": { "require_debug_true": {
"()": "django.utils.log.RequireDebugTrue", "()": "django.utils.log.RequireDebugTrue",
}, },
"skip_variable_doesnotexist": {
"()": "evibes.settings.logconfig.SkipVariableDoesNotExistFilter",
},
}, },
"handlers": { "handlers": {
"console_debug": { "console_debug": {
@ -61,6 +77,12 @@ LOGGING = {
"level": "WARNING", "level": "WARNING",
"propagate": False, "propagate": False,
}, },
"django.template": {
"handlers": ["console_debug", "console_production"],
"level": "DEBUG" if DEBUG else "INFO", # noqa: F405
"propagate": True,
"filters": ["skip_variable_doesnotexist"],
},
"evibes": { "evibes": {
"handlers": ["console_debug" if DEBUG else "console_production"], # noqa: F405 "handlers": ["console_debug" if DEBUG else "console_production"], # noqa: F405
"level": "DEBUG" if DEBUG else "WARNING", # noqa: F405 "level": "DEBUG" if DEBUG else "WARNING", # noqa: F405