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)
我在模型的 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)