Ecco la mia soluzione generica che utilizza il reindirizzamento, controlla solo se ci sono parametri GET, se non ne esistono, reindirizza con il parametro get predefinito. Ho anche un set list_filter in modo che lo raccolga e visualizzi il valore predefinito.
from django.shortcuts import redirect
class MyModelAdmin(admin.ModelAdmin):
...
list_filter = ('status', )
def changelist_view(self, request, extra_context=None):
referrer = request.META.get('HTTP_REFERER', '')
get_param = "status__exact=5"
if len(request.GET) == 0 and '?' not in referrer:
return redirect("{url}?{get_parms}".format(url=request.path, get_parms=get_param))
return super(MyModelAdmin,self).changelist_view(request, extra_context=extra_context)
L'unico avvertimento è quando accedi direttamente alla pagina con "?" presente nell'URL, non è impostato alcun HTTP_REFERER, quindi utilizzerà il parametro predefinito e il reindirizzamento. Per me va bene, funziona benissimo quando fai clic sul filtro dell'amministratore.
AGGIORNAMENTO :
Per aggirare l'avvertenza, ho finito per scrivere una funzione di filtro personalizzata che semplificava la funzionalità changelist_view. Ecco il filtro:
class MyModelStatusFilter(admin.SimpleListFilter):
title = _('Status')
parameter_name = 'status'
def lookups(self, request, model_admin): # Available Values / Status Codes etc..
return (
(8, _('All')),
(0, _('Incomplete')),
(5, _('Pending')),
(6, _('Selected')),
(7, _('Accepted')),
)
def choices(self, cl): # Overwrite this method to prevent the default "All"
from django.utils.encoding import force_text
for lookup, title in self.lookup_choices:
yield {
'selected': self.value() == force_text(lookup),
'query_string': cl.get_query_string({
self.parameter_name: lookup,
}, []),
'display': title,
}
def queryset(self, request, queryset): # Run the queryset based on your lookup values
if self.value() is None:
return queryset.filter(status=5)
elif int(self.value()) == 0:
return queryset.filter(status__lte=4)
elif int(self.value()) == 8:
return queryset.all()
elif int(self.value()) >= 5:
return queryset.filter(status=self.value())
return queryset.filter(status=5)
E changelist_view ora passa solo il parametro predefinito se non ce ne sono. L'idea era di eliminare la capacità dei filtri generici di visualizzare tutto senza utilizzare parametri get. Per visualizzare tutto ho assegnato lo stato = 8 a tale scopo:
class MyModelAdmin(admin.ModelAdmin):
...
list_filter = ('status', )
def changelist_view(self, request, extra_context=None):
if len(request.GET) == 0:
get_param = "status=5"
return redirect("{url}?{get_parms}".format(url=request.path, get_parms=get_param))
return super(MyModelAdmin, self).changelist_view(request, extra_context=extra_context)