Voici ma solution générique utilisant la redirection, elle vérifie simplement s'il existe des paramètres GET, s'il n'en existe pas, elle redirige avec le paramètre get par défaut. J'ai également un list_filter défini pour qu'il le récupère et affiche la valeur par défaut.
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)
La seule mise en garde est lorsque vous accédez directement à la page avec "?" présent dans l'url, il n'y a pas de jeu HTTP_REFERER donc il utilisera le paramètre par défaut et redirigera. Cela me convient, cela fonctionne très bien lorsque vous cliquez sur le filtre d'administration.
MISE À JOUR :
Afin de contourner la mise en garde, j'ai fini par écrire une fonction de filtre personnalisée qui simplifiait la fonctionnalité changelist_view. Voici le filtre:
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)
Et le changelist_view ne transmet désormais le paramètre par défaut que si aucun n'est présent. L'idée était de se débarrasser de la capacité des filtres génériques à tout afficher en n'utilisant aucun paramètre get. Pour voir tout, j'ai attribué le statut = 8 à cette fin:
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)