2👍
This appears to be a bug in Django, when you have double-underscores for the filter path (first element of the tuple)… in your case 'model1__model2__property'
NOTE: now fixed in Django 1.7
More details here:
https://code.djangoproject.com/ticket/19182
It’s quite ugly but so far the only workaround I found was to paste this fixed and overridden method into the ModelAdmin
where you want to use that list_filter
:
def lookup_allowed(self, lookup, value):
"""
Copy and pasted from ModelAdmin to fix bug in Django
https://code.djangoproject.com/ticket/19182
"""
from django.db.models.constants import LOOKUP_SEP
from django.db.models.sql.constants import QUERY_TERMS
from django.contrib.admin import FieldListFilter
from django.contrib.admin import widgets
model = self.model
# Check FKey lookups that are allowed, so that popups produced by
# ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
# are allowed to work.
for l in model._meta.related_fkey_lookups:
for k, v in widgets.url_params_from_lookup_dict(l).items():
if k == lookup and v == value:
return True
parts = lookup.split(LOOKUP_SEP)
# Last term in lookup is a query term (__exact, __startswith etc)
# This term can be ignored.
if len(parts) > 1 and parts[-1] in QUERY_TERMS:
parts.pop()
# Special case -- foo__id__exact and foo__id queries are implied
# if foo has been specificially included in the lookup list; so
# drop __id if it is the last part. However, first we need to find
# the pk attribute name.
rel_name = None
for part in parts[:-1]:
try:
field, _, _, _ = model._meta.get_field_by_name(part)
except FieldDoesNotExist:
# Lookups on non-existants fields are ok, since they're ignored
# later.
return True
if hasattr(field, 'rel'):
model = field.rel.to
rel_name = field.rel.get_related_field().name
elif isinstance(field, RelatedObject):
model = field.model
rel_name = model._meta.pk.name
else:
rel_name = None
if rel_name and len(parts) > 1 and parts[-1] == rel_name:
parts.pop()
if len(parts) == 1:
return True
clean_lookup = LOOKUP_SEP.join(parts)
// FIX BEGINS:
valid_lookups = [self.date_hierarchy]
for filter_item in self.list_filter:
if callable(filter_item):
valid_lookups.append(filter_item.parameter_name)
elif isinstance(filter_item, (list, tuple)):
valid_lookups.append(filter_item[0])
else:
valid_lookups.append(filter_item)
return clean_lookup in valid_lookups
Source:stackexchange.com