2012-08-24 10 views
26

Chciałbym zrobić niestandardowe filtry dla administratora django zamiast zwykłych "is_staff" i "is_superuser". Przeczytałem ten dokument list_filter w dokumentach Django. Własne Filtry działają w ten sposób:Tworzenie niestandardowych filtrów dla list_filter w Django Admin

from datetime import date 

from django.utils.translation import ugettext_lazy as _ 
from django.contrib.admin import SimpleListFilter 

class DecadeBornListFilter(SimpleListFilter): 
    # Human-readable title which will be displayed in the 
    # right admin sidebar just above the filter options. 
    title = _('decade born') 

    # Parameter for the filter that will be used in the URL query. 
    parameter_name = 'decade' 

    def lookups(self, request, model_admin): 
     """ 
     Returns a list of tuples. The first element in each 
     tuple is the coded value for the option that will 
     appear in the URL query. The second element is the 
     human-readable name for the option that will appear 
     in the right sidebar. 
     """ 
     return (
      ('80s', _('in the eighties')), 
      ('90s', _('in the nineties')), 
     ) 

    def queryset(self, request, queryset): 
     """ 
     Returns the filtered queryset based on the value 
     provided in the query string and retrievable via 
     `self.value()`. 
     """ 
     # Compare the requested value (either '80s' or '90s') 
     # to decide how to filter the queryset. 
     if self.value() == '80s': 
      return queryset.filter(birthday__gte=date(1980, 1, 1), 
            birthday__lte=date(1989, 12, 31)) 
     if self.value() == '90s': 
      return queryset.filter(birthday__gte=date(1990, 1, 1), 
            birthday__lte=date(1999, 12, 31)) 

class PersonAdmin(ModelAdmin): 
    list_filter = (DecadeBornListFilter,) 

ale mam już funkcje niestandardowe list_display tak:

def Student_Country(self, obj): 
    return '%s' % obj.country 
Student_Country.short_description = 'Student-Country' 

Czy to możliwe, że mogę korzystać z funkcji niestandardowych list_display w list_filter zamiast piśmie nowa funkcja niestandardowa dla list_filtra? Wszelkie sugestie i ulepszenia są mile widziane .. Potrzebują wskazówek na ten temat ... Dzięki ...

+0

http: // stackoverflow. com/questions/12215751/can-i-make-list-filter-in-django-admin-only-show-referenced-foreignkeys – user956424

Odpowiedz

1

Twoja metoda list_display zwraca ciąg znaków, ale jeśli dobrze rozumiem, to co chcesz zrobić, to dodać filtr, który umożliwia wybór krajów studentów, prawda?

Dla tego prostego filtru relacji, a właściwie dla kolumny "Kraj studenta", nie trzeba tworzyć niestandardowej klasy filtrów ani niestandardowej metody wyświetlania listy; to wystarczy:

class MyAdmin(admin.ModelAdmin): 
    list_display = ('country',) 
    list_filter = ('country',) 

Sposób Django robi list_filter, jak wyjaśniono in the docs, to najpierw automatycznie dopasowane pól, które dostarczają do gotowych klas filtrów; te filtry to CharField i ForeignKey.

list_display podobnie automatyzuje populacji kolumny listy zmian z wykorzystaniem pola przekazywane przez pobieranie pokrewnych przedmiotów i powracania unikodzie wartości są (podobnie jak w sposób podany powyżej).

5

Rzeczywiście można dodać niestandardowe filtry do filtrów administracyjnych poprzez rozszerzenie SimpleListFilter. Na przykład, jeśli chcesz dodać filtr kontynent „Afryka” do filtra kraj administratora używanego powyżej, można wykonać następujące czynności:

W admin.py:

from django.contrib.admin import SimpleListFilter 

class CountryFilter(SimpleListFilter): 
    title = 'country' # or use _('country') for translated title 
    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] + [ 
      ('AFRICA', 'AFRICA - ALL')] 

    def queryset(self, request, queryset): 
     if self.value() == 'AFRICA': 
      return queryset.filter(country__continent='Africa') 
     if self.value(): 
      return queryset.filter(country__id__exact=self.value()) 

class CityAdmin(ModelAdmin): 
    list_filter = (CountryFilter,) 
Powiązane problemy