Django 管理员重置过滤器选择的搜索框查询

Django admin reset search box query on filter selection

我在模型的 Django 管理中有以下 class:

class TopUpsAdmin(admin.ModelAdmin):
    search_fields = ('user__email', 'user__phone_number',)
    list_filter = ('status',)

当前过滤器的默认行为是

if search box in the listing page is input with test_1 which is a user name and search up the result(url will have the following parameter /?q=test_1) , if select an option in the filter then the filter results also got affected by the search box query on the URL ?q=test_1&status__exact=1)

我不希望在选择过滤器时让搜索结果过滤列表。

阅读 Django docs 只告诉我如何用参数中的现有查询(来自搜索框)覆盖过滤器。

任何帮助将不胜感激

我认为您可以覆盖 get_search_results 方法。见文档:https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_search_results

示例:

class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'age')
    search_fields = ('name',)

    def get_search_results(self, request, queryset, search_term):
        if len(request.GET) > 1:
            search_term = None
        queryset, use_distinct = super().get_search_results(request,
                                                            queryset,
                                                            search_term)
        return queryset, use_distinct

创建一个 Admin SimpleListFilter 并应用下面的 mixin

from django.utils.translation import gettext_lazy as _

class FilterMixin:
    def choices(self, changelist):
        yield {
            'selected': self.value() is None,
            'query_string': changelist.get_query_string(remove=[self.parameter_name, <b>'q'</b>]),
            'display': _('All'),
        }
        for lookup, title in self.lookup_choices:
            yield {
                'selected': self.value() == str(lookup),
                'query_string': changelist.get_query_string({self.parameter_name: lookup}, <b>remove=['q']</b>),
                'display': title,
            }

完整的代码库

#models.py
class Person(models.Model):
    class GenderChoice(models.IntegerChoices):
        MALE = 1
        FEMALE = 2
        OTHER = 3

    name = models.CharField(max_length=20)
    gender = models.IntegerField(choices=GenderChoice.choices)

    def __str__(self):
        return self.name

# admin.py
class GenderFilter(<b>FilterMixin, admin.SimpleListFilter</b>):
    title = 'Gender'
    parameter_name = 'gender'

    def lookups(self, request, model_admin):
        return Person.GenderChoice.choices

    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(**{'gender': int(self.value())})
        else:
            return queryset


class PersonAdmin(admin.ModelAdmin):
    search_fields = ('name',)
    <b>list_filter = (GenderFilter,)</b>


admin.site.register(Person, PersonAdmin)