Django Admin: Как установить фильтр по умолчанию, не конфликтуя с выбранными пользователем фильтрами?
Я работаю с панелью Django Admin и мне нужно установить фильтр по умолчанию для представления списка изменений модели. Когда пользователь открывает страницу списка изменений в первый раз, я хочу, чтобы она автоматически фильтровалась по определенному значению (например, status="A"). Однако, когда пользователь выбирает другой фильтр (например, status="B"), фильтр по умолчанию (status="A") не должен применяться.
Что я пробовал: Я переопределил метод changelist_view в классе ModelAdmin, чтобы проверить, присутствует ли в запросе какой-либо фильтр статуса. Если нет, я добавляю фильтр по умолчанию (status=A). Вот как выглядит мой код:
from django.contrib import admin
from django.shortcuts import redirect
from django.urls import reverse
from .models import Person # Replace with your actual model
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'status') # Adjust fields to match your model
list_filter = ('status',) # Adjust filters to match your model
def get_queryset(self, request):
# Get the original queryset without any default filtering
qs = super().get_queryset(request)
return qs
def changelist_view(self, request, extra_context=None):
# Check if any filters related to 'status' are already applied by looking at request.GET
if 'status' not in request.GET and 'status__exact' not in request.GET:
# Redirect to the same changelist URL with the default filter applied
query = request.GET.copy() # Make a mutable copy of GET parameters
query['status'] = 'A' # Set the default filter value for 'status' to 'A'
# Redirect to the changelist URL with the correct query string
return redirect(
f"{reverse('admin:Human_Resource_Management_person_changelist')}?{query.urlencode()}"
)
# Call the original changelist_view method
return super().changelist_view(request, extra_context=extra_context)
# Register your admin class with the associated model
admin.site.register(Person, PersonAdmin)
<
Изначально код работает: когда представление списка изменений загружается без каких-либо фильтров, по умолчанию устанавливается статус=A. Однако если пользователь выбирает другой фильтр, например status=B, то URL выглядит следующим образом: ?status=A&status__exact=B В результате оба фильтра применяются одновременно, что неправильно. Я хочу, чтобы применялся только выбранный пользователем фильтр (например, status=B) и не сохранялся фильтр по умолчанию (status=A) в URL.
Что я пробовал: Я пробовал изменять request.GET напрямую, но это вызвало ошибку AttributeError, поскольку request.GET неизменяем. Я также пробовал более сложные проверки условий, но, похоже, не могу предотвратить сохранение фильтра status=A в URL при выборе другого фильтра. Что я ищу: Я ищу решение, которое:
Применяет фильтр по умолчанию (status=A) только в том случае, если нет другого фильтра статуса. Удаляет фильтр по умолчанию, когда пользователь выбирает другой фильтр (status=B), чтобы избежать конфликтующих фильтров в URL. Любые соображения или предложения о том, как этого добиться, будут высоко оценены!
Спасибо!
Фильтр отбрасывает предыдущий фильтр с тем же именем. Но вы используете status
, а не status__exact
, отсюда и проблема. Вместо этого используйте status__exact
:
class PersonAdmin(admin.ModelAdmin):
# …
def changelist_view(self, request, extra_context=None):
if 'status' not in request.GET and 'status__exact' not in request.GET:
# Redirect to the same changelist URL with the default filter applied
query = request.GET.copy() # Make a mutable copy of GET parameters
query['status__exact'] = 'A' # Set the default filter value for 'status' to 'A'
# Redirect to the changelist URL with the correct query string
return redirect(
f"{reverse('admin:Human_Resource_Management_person_changelist')}?{query.urlencode()}"
)
# Call the original changelist_view method
return super().changelist_view(request, extra_context=extra_context)