Я пытаюсь реализовать новую версию этого фрагмента, чтобы сделать его совместимым с Django 1.4 и 1.5.
Довольно много изменений, приведенный ниже код почти работает, за исключением того, что Django возвращает мне ошибку SuspiciousOperation. Я вижу, как я мог бы взломать его, но я бы предпочел не трогать ядро Django. Если у вас есть предложения, добро пожаловать:
Вот мой фильтр:
class RelatedNullFilterSpec(FieldListFilter):
def __init__(self, field, request, params, model, model_admin, field_path):
field_root, field_name = field_path.rsplit('__', 1)
self.lookup_title = field.verbose_name
self.title = self.lookup_title
self.null_lookup_kwarg = '%s__isnull' % field_root
self.null_lookup_val = request.GET.get(self.null_lookup_kwarg, None)
self.lookup_kwarg = '%s__exact' % (field_path)
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
if isinstance(field, models.fields.BooleanField):
self.lookup_choices = (
# (None, _('All')),
('1', _('Yes')),
('0', _('No')))
else:
self.lookup_choices = field.get_choices(include_blank=False)
super(RelatedNullFilterSpec, self).__init__(field, request, params, model, model_admin, field_path)
def expected_parameters(self):
return [self.lookup_kwarg, self.null_lookup_kwarg]
def choices(self, cl):
yield {'selected': self.lookup_val is None and self.null_lookup_val is None,
'query_string': cl.get_query_string({}, [self.lookup_kwarg,self.null_lookup_kwarg]),
'display': _('All')}
yield {'selected': self.lookup_val is None and self.null_lookup_val=="True",
'query_string': cl.get_query_string({self.null_lookup_kwarg:True},[self.lookup_kwarg]),
'display': _('Null')}
yield {'selected': self.lookup_val is None and self.null_lookup_val=="False",
'query_string': cl.get_query_string({self.null_lookup_kwarg:False},[self.lookup_kwarg]),
'display': _('Not Null')}
for pk_val, val in self.lookup_choices:
yield {'selected': self.lookup_val == smart_unicode(pk_val),
'query_string': cl.get_query_string({self.lookup_kwarg: pk_val},[self.null_lookup_kwarg]),
'display': val}
Затем в моем администраторе у меня есть следующее:
list_filter = ('time_added', 'time_modified', ('model1__model2__property', RelatedNullFilterSpec),)
И я всегда получал эту ошибку от метода lookup_allowed
класса Django BaseModelAdmin...
В django.db.models.options я мог бы реализовать хак для перезаписи или расширения self.related_fkey_lookups
, но на мой вкус это слишком хакерски.
РЕДАКТИРОВАТЬ: обратите внимание, что следующий почти стандартный фильтр также возвращает ту же ошибку: ('venue__eat_venue', BooleanFieldListFilter)
В общем, моя цель состоит в том, что мне нужен фильтр, который позволяет мне сортировать объекты по наличию/отсутствию поля, связанного с model2 (Null/Not-Null), и по значениям свойства (в случае, если поле, связанное с model2, существует ). Это было бы очень удобно, и я не думаю, что это слишком конкретно.
И, наконец, да, все работает, когда я не запрашиваю этот пользовательский фильтр для своего model1__model2__property
:-)