我正在使用Django 1.7.4。我想在过滤器中仅显示在CarMake模型的外国领域中使用的国家。我尝试了两种变体,但它不起作用。如果我在list_filter中简单地放入'country',它会显示所有国家/地区。我做错了什么?
#model.py
from apps.location.models import Country
class CarMake(BaseModel):
name = models.CharField(max_length=100)
country = models.ForeignKey(Country, blank=True, null=True)
def __str__(self):
return self.name
from . import models
class CarMakeAdmin(admin.ModelAdmin):
model = models.CarMake
list_display = ('name', 'country')
list_filter = (
#(CountryFilter), -> Variant I
('country', 'RelatedOnlyFieldListFilter'), #Variant II
)
变体I
class CountryFilter(admin.SimpleListFilter):
title = _('by country')
parameter_name = 'country'
def lookups(self, request, model_admin):
countries = set([c.country for c in model_admin.model.objects.all()])
return [(c.id, c.name) for c in countries]
def queryset(self, request, queryset):
if self.value():
return queryset.filter(country__id__exact=self.value())
else:
return queryset
变体II
class RelatedOnlyFieldListFilter(admin.RelatedFieldListFilter):
def __init__(self, field, request, params, model, model_admin, field_path):
self.request = request
self.model_admin = model_admin
super(RelatedOnlyFieldListFilter, self).__init__(field, request, params, model, model_admin, field_path)
def choices(self, cl):
limit_choices_to = set(self.model_admin.queryset(self.request).values_list(self.field.name, flat=True))
self.lookup_choices = [(pk_val, val) for pk_val, val in self.lookup_choices if pk_val in limit_choices_to]
return super(RelatedOnlyFieldListFilter, self).choices(cl)
答案 0 :(得分:5)
最后,我找到了解决问题的方法。
class CountryFilter(admin.SimpleListFilter):
title = _('Country')
parameter_name = 'country'
def lookups(self, request, model_admin):
countries = []
qs = Country.objects.filter(id__in = model_admin.model.objects.all().values_list('country_id', flat = True).distinct())
for c in qs:
countries.append([c.id, c.name])
return countries
def queryset(self, request, queryset):
if self.value():
return queryset.filter(country__id__exact=self.value())
else:
return queryset