10 votes

Django admin affiche le champ uniquement si la case à cocher est fausse

Models.py

class Menu(models.Model):

    ...
    has_submenu=models.BooleanField(default=1)
    page=models.ForeignKey(Page,null=True)

Je veux que l'admin de django affiche l'attribut de la page seulement si la case à cocher has_submenu est fausse (Donc django-admin doit écrire du javascript pour moi :) )

Peut-être que je dois étendre la méthode render_change_form

Des conseils?

24voto

Chris P Points 797

Vous pouvez utiliser jQuery dans l'interface d'administration de Django:

class MenuAdmin(admin.ModelAdmin):
    # ...
    class Media:
        js = ('/static/admin/js/hide_attribute.js',)

ModelAdmin et InlineModelAdmin ont une propriété media qui renvoie une liste d'objets Media qui stockent les chemins des fichiers JavaScript pour les formulaires et/ou les ensembles de formulaires.

Contenu de hide_attribute.js :

hide_page=false;
django.jQuery(document).ready(function(){
    if (django.jQuery('#id_has_submenu').is(':checked')) {
        django.jQuery(".page").hide();
        hide_page=true;
    } else {
        django.jQuery(".page").show();
        hide_page=false;
    }
    django.jQuery("#id_has_submenu").click(function(){
        hide_page=!hide_page;
        if (hide_page) {
            django.jQuery(".page").hide();
        } else {
            django.jQuery(".page").show();
        }
    })
})

Namespace :

Pour éviter les conflits avec les scripts ou bibliothèques fournis par l'utilisateur, le jQuery de Django (version 3.3.1) est namespaceé en tant que django.jQuery.

3voto

alecxe Points 50783

Que diriez-vous de remplacer la méthode get_form dans un ModelAdmin, comme ceci :

class MenuModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        self.exclude = []
        if obj and obj.has_submenu:
            self.exclude.append('page')
        return super(MenuModelAdmin, self).get_form(request, obj, **kwargs)

Veuillez également consulter la documentation sur get_form.

2voto

Snala Points 23

En fait, j'ai dû modifier un peu cela et j'ai pensé partager ce que j'ai fait ici au cas où quelqu'un d'autre tombe sur ce post. Il y avait trois principaux points que j'ai dû prendre en compte :

  1. Les erreurs fréquentes se produisent car elle tente de charger django.jQuery avant qu'il ne soit prêt.
  2. Hide ne fonctionnait pas en général (je ne sais pas pourquoi)
  3. Je voulais faire l'inverse, cacher sauf si l'option était cochée.

Donc, cela résout ces trois problèmes pour moi. Nous faisons ce qui suit :

  1. Retarder l'appel de la fonction
  2. Cacher le .form-row.field-, pour cacher une ligne entière (je recommande d'utiliser la fonction d'inspection de Chrome pour trouver le nom de la ligne que vous voulez cacher.)
  3. Nous faisons l'inverse, cachant la section dès que la page est chargée et la réaffichant si la case est cochée.

Voici donc mon code final :

window.addEventListener("load", function() {
    (function() {
        show_page=false;
        django.jQuery(document).ready(function(){
            if (django.jQuery('#id_override_timeline').is(':checked')) {
                django.jQuery(".form-row.field-next_milestone").show();
                show_page=true;
            } else {
                django.jQuery(".form-row.field-next_milestone").hide();
                show_page=false;
            }
            django.jQuery("#id_override_timeline").click(function(){
                show_page=!show_page;
                if (show_page) {
                    django.jQuery(".form-row.field-next_milestone").show();
                } else {
                    django.jQuery(".form-row.field-next_milestone").hide();
                }
            })
        })
    })(django.jQuery);
});

J'espère que cela aidera quelqu'un d'autre qui tombe sur ce post !

1voto

user1802310 Points 126

Vous pouvez étendre le modèle d'administration de Django.

Suivez simplement cette structure:

Dans l'ensemble d'un projet:

templates/admin/change_form.html

Dans une application

templates/admin//change_form.html

Dans un modèle

templates/admin///change_form.html

Dans votre cas, il semble que vous n'ayez qu'à étendre le modèle de menu. Je ferais ce qui suit:

  1. Récupérez le modèle change_form.html dans le dossier django
  2. À l'intérieur de la boucle d'objets, cherchez le champ page
  3. Faites la vérification de condition sur has_submenu pour décider s'il faut afficher ou non l'attribut page

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X