У меня есть модель:
class Foo(models.Model):
attribute = models.IntegerField()
user = models.ForeignKey(user)
и администратор модели:
class FooAdmin(admin.ModelAdmin):
list_filter = ('attribute',)
В администраторе я отображаю только объекты Foo активного пользователя, но фильтр атрибутовдайте мне все возможные атрибуты, даже те, которые не возвращают никаких объектов для этого пользователя.В конце у меня много разных значений фильтра, и большинство из них бесполезны для пользователя.Как я могу ограничить эти значения фильтра теми, которые соответствуют пользователю.
надеюсь, что это понятно
Приветствия
Решение: В admin.pyв вашем приложении укажите:
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec
from django.contrib.auth.models import User
from sets import Set
class CustomChoiceFilterSpec(ChoicesFilterSpec):
def __init__(self, f, request, params, model, model_admin):
super(CustomChoiceFilterSpec, self).__init__(f, request, params, model,
model_admin)
self.lookup_kwarg = '%s__attribute__exact' % f.name
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.objects = list(Set([i.attribute for i in model.objects.filter(foo__user = request.user)])) # This is the magic line :) !
def choices(self, cl):
yield {'selected': self.lookup_val is None,
'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
'display': ('All')}
for val in self.objects:
yield {'selected': smart_unicode(val) == self.lookup_val,
'query_string': cl.get_query_string({self.lookup_kwarg: val.attribute}),
'display': val.attribute}
def title(self):
return "Attribute"
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'compact_filter', False), CustomChoiceFilterSpec))
В последней строке указано, что этот тип фильтра будет применяться только к объектам, для которых в качестве атрибута указан 'compact_filter'.
Поэтому мы добавили в нашу модель Foo(models.py):
attribute.compact_filter = True