Есть простой способ сделать это, но это не общее решение и требует модификации каждого ModelAdmin
, который вы хотите поддержать. Возможно, есть общий способ сделать это, но я не потратил время на его решение на общем уровне.
Первым шагом является написание пользовательского FilterSpec
для фильтра (см. Сообщение Харли о ссылках, которые помогут), который сохраняет выбранное значение фильтра в сеансе (и удаляет его, когда он больше не нужен).
# in cust_admin/filterspecs.py
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec
class MyFilterSpec(ChoicesFilterSpec):
def __init__(self, f, request, params, model, model_admin):
super(MyFilterSpec, self).__init__(f, request, params, model,
model_admin)
if self.lookup_val is not None:
request.session[self.lookup_kwarg] = self.lookup_val
elif self.lookup_kwarg in request.session:
del(request.session[self.lookup_kwarg])
# Register the filter with a test function which will apply it to any field
# with a my_filter attribute equal to True
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'my_filter', False),
MyFilterSpec))
Вы должны импортировать модуль, в котором он находится, например, ваш urls.py
:
# in urls.py
from cust_admin import filterspecs
Установите свойство в поле, к которому вы хотите применить фильтр:
# in models.py
class MyModel(models.Model):
my_field = Models.IntegerField(choices=MY_CHOICES)
my_field.my_filter = True
В пользовательском классе ModelAdmin
переопределите метод change_view
, чтобы после нажатия пользователем кнопки save они возвращались в список со значением поля фильтра, добавленным к URL-адресу.
class MyModelAdmin(admin.ModelAdmin):
def change_view(self, request, object_id, extra_context=None):
result = super(MyModelAdmin, self).change_view(request, object_id,
extra_context)
if '_save' in request.POST:
if 'my_field__exact' in request.session:
result['Location'] = '/admin/myapp/mymodel/?my_field__exact=%s' \
% request.session['my_field__exact']
return result