Question

Ce que je voudrais accomplir est:

  • Je vais sur le site d'administration, j'applique des filtres à la liste d'objets
  • Je clique sur un objet et le modifie, édite, édite et clique sur "Enregistrer"
  • Le site m'amène à la liste des objets ... non filtrés. J'aimerais que le filtre de l'étape 1 soit mémorisé et appliqué.

Existe-t-il un moyen facile de le faire?

Était-ce utile?

La solution

Malheureusement, il n’ya pas de moyen facile de le faire. Le filtrage ne semble pas être enregistré dans aucune variable de session.

Il est normal de cliquer deux fois en arrière, mais cela peut être fastidieux et ennuyeux si vous venez de modifier un objet afin qu'il ne soit plus affiché à l'aide de votre filtre.

S'il ne s'agit que d'une seule opération, cliquez deux fois en arrière ou procédez à nouveau au filtrage, c'est le moyen le plus simple.

Si vous filtrez plus souvent, ou si vous voulez juste apprendre à pirater l'administrateur (qui est assez ouvert et facile), vous voudrez écrire un FilterSpec .

Consultez ici et ici pour des exemples de personnes écrivant leurs propres.

Une très très mauvaise façon de procéder consiste à modifier l'interface d'administration de manière à ce que, une fois que vous avez cliqué sur "Enregistrer", vous soyez redirigé vers votre URL filtrée. Je ne le recommanderais pas du tout, mais c'est une option.

Un autre moyen assez simple de le faire serait d’écrire une vue générique pour montrer vos objets filtrés, puis d’utiliser des formulaires Django pour éditer les éléments à partir de là. Je jetterais un coup d'œil à ça, vous serez étonné du peu de code que vous devez écrire pour obtenir une simple page de vue / modification.

Autres conseils

Cliquez deux fois sur "Retour"?

Il existe un hack simple pour faire cela, mais ce n’est pas une solution générale, il faut modifier chaque ModelAdmin pour lequel vous voulez le supporter. Il existe peut-être un moyen général de le faire, mais je n’ai pas passé le temps de le résoudre au niveau général.

La première étape consiste à écrire un FilterSpec personnalisé pour le filtre (voir l'article de Harley pour des liens utiles) qui enregistre la valeur du filtre choisi dans la session (et la supprime lorsqu'elle n'est plus utile). .

# in cust_admin/filterspecs.py
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec

class MyFilterSpec(ChoicesFilterSpec):

    def __init__(self, f, request, params, model, model_admin):
        super(MyFilterSpec, self).__init__(f, request, params, model,
                                           model_admin)
        if self.lookup_val is not None:
            request.session[self.lookup_kwarg] = self.lookup_val
        elif self.lookup_kwarg in request.session:
            del(request.session[self.lookup_kwarg])

# Register the filter with a test function which will apply it to any field
# with a my_filter attribute equal to True
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'my_filter', False),
                               MyFilterSpec))

Vous devez importer le module qui se trouve quelque part, par exemple votre urls.py :

# in urls.py
from cust_admin import filterspecs

Définissez une propriété sur le champ auquel vous souhaitez appliquer le filtre:

# in models.py
class MyModel(models.Model):
    my_field = Models.IntegerField(choices=MY_CHOICES)
    my_field.my_filter = True

Dans une classe personnalisée ModelAdmin , remplacez la méthode change_view , afin que l'utilisateur clique sur Enregistrer pour revenir à la vue Liste. avec leur valeur de champ de filtre ajoutée à l'URL.

class MyModelAdmin(admin.ModelAdmin):
    def change_view(self, request, object_id, extra_context=None):
        result = super(MyModelAdmin, self).change_view(request, object_id,
                                                       extra_context)
        if '_save' in request.POST:
            if 'my_field__exact' in request.session:
                result['Location'] = '/admin/myapp/mymodel/?my_field__exact=%s' \
                                     % request.session['my_field__exact']
        return result

Une autre façon de procéder consiste à incorporer le filtre dans le jeu de requêtes.

Vous pouvez créer de manière dynamique un modèle de proxy avec un gestionnaire qui filtre comme vous le souhaitez, puis appelez admin.site.register () pour créer un nouvel administrateur de modèle. Tous les liens seraient alors relatifs à cette vue.

À mon avis, il est préférable de remplacer les méthodes ModelAdmin changelist_view et change_view :

Comme si:

class FakturaAdmin(admin.ModelAdmin):

[...]

def changelist_view(self, request, extra_context=None):
    result = super(FakturaAdmin, self).changelist_view(request, extra_context=None)
    request.session['qdict'] = request.GET
    return result

def change_view(self, request, object_id, extra_context=None):
    result = super(FakturaAdmin, self).change_view(request, object_id, extra_context)
    try:
        result['location'] = result['location']+"?"+request.session['qdict'].urlencode()
    except:
        pass
    return result

Comme vous le souhaitez, après avoir sauvegardé l'objet, vous revenez à la liste des objets avec des filtres actifs.

Il existe une demande de modification au projet Django demandant exactement cette fonctionnalité.

Il ne reste plus que quelques tests à effectuer, ainsi que de la documentation. Vous pouvez les écrire et aider l’ensemble du projet, ou simplement prendre le correctif proposé (au bas de la page) et l’essayer.

https://code.djangoproject.com/ticket/6903

Cette fonctionnalité a été ajoutée à Django dans le cadre de la version 1.6 et est maintenant activée par défaut. Il est décrit dans les notes de publication :

  

ModelAdmin conserve désormais les filtres dans la vue liste après la création,   éditer ou supprimer un objet. Il est possible de restaurer le précédent   comportement d'effacement des filtres en définissant l'attribut preserve_filters   à False.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top