[PYTHON] Implémentation du menu déroulant dans Django

Image d'implémentation

スクリーンショット 2020-08-17 14.54.31.png

Créez quelque chose comme ceci: lorsque vous cliquez sur une lettre, les éléments de la couche inférieure s'affichent. (Celui ci-dessus a une case à cocher, mais pour le moment, je vise à afficher les données de la base de données dans une structure hiérarchique sans case à cocher.)

Mise en œuvre 1 (date)

Tout d'abord, préparez les données à utiliser. Cette fois, préparez le DB et les données de sorte que la catégorie parent → catégorie enfant → catégorie petit-enfant comme indiqué dans l'image. Ajoutez ce qui suit à models.py.

models.py


class CategoryIDModels(models.Model):
    class Meta:
        db_table = 'CategoryID'

    CategoryID = models.CharField(
        primary_key=True,
        verbose_name='CategoryID',
        blank=False,
        null=False,
        max_length=20,
        default='',
    )

    Category_name = models.CharField(
        verbose_name='Nom de catégorie',
        blank=False,
        null=False,
        max_length=225,
        default='',
    )
class CategoryID2Models(models.Model):
    class Meta:
        db_table = 'CategoryID2'

    CategoryID = models.CharField(
        primary_key=True,
        verbose_name='CategoryID',
        blank=False,
        null=False,
        max_length=20,
        default='',
    )

    Category_name = models.CharField(
        verbose_name='Nom de catégorie',
        blank=False,
        null=False,
        max_length=225,
        default='',
    )

    ParentCategoryID = models.ForeignKey(
        CategoryIDModels, 
        to_field='CategoryID',
        verbose_name='Catégorie Parentale',
        on_delete=models.CASCADE,
        null=True
    )
class CategoryID3Models(models.Model):
    class Meta:
        db_table = 'CategoryID3'

    CategoryID = models.CharField(
        primary_key=True,
        verbose_name='CategoryID',
        blank=False,
        null=False,
        max_length=20,
        default='',
    )

    Category_name = models.CharField(
        verbose_name='Nom de catégorie',
        blank=False,
        null=False,
        max_length=225,
        default='',
    )

    ParentCategoryID = models.ForeignKey(
        CategoryID2Models, 
        to_field='CategoryID',
        verbose_name='Catégorie Parentale',
        on_delete=models.CASCADE,
        null=True
    )

CategoryIDmodels (parent) -> CategoryID2models (child) -> CategoryID3models (petit-enfant) CategoryID2 et 3 définissent la colonne "CategoryID" de la couche supérieure comme ForeignKey.

Les données à saisir sont les suivantes. スクリーンショット 2020-08-20 10.42.03.png

En outre, lors de la saisie de données, CategoryID2Models et CategoryID3Models doivent également définir la colonne ParentCategoryID. Voir la documentation officielle et ci-dessous pour ForeignKey.

Construisez un modèle un-à-plusieurs avec Django ForeignKey

Implémentation 2 (HTML)

Ensuite, préparez le côté html. Créez "Dropmenu.html" dans le dossier des modèles du projet.

Dropmenu.html


<!DOCTYPE html>

{% load static %}
{% load Drop %}

<html lang="ja">
    <head>
      <meta charset="utf-8">
      <link rel="stylesheet" type="text/CSS" href="{% static 'css/drop.css' %}" />
      <title>{% block title %}DropMenu{% endblock %}</title>
    </head>
    <body>
        {% csrf_token %}
        {% for data in form %}
        <span><p id="click_event" style="display:inline;">{{data.Category_name}}</p></span>
              <ul>
                {% for things in form_child|in_category:data.CategoryID %}
                <li><p id="click_event2" style="display:inline;">{{things.Category_name}}</p>
                    <ul>
                    {% for thing in form_gchild|in_category:things.CategoryID %}
                      <li>{{thing.Category_name}}</li>
                    {% endfor %}
                    </ul>
                </li>
                {% endfor %}
              </ul>
        {% endfor %}
            <script type="text/javascript">
              $(function () {
                //Traitement du menu parent
                $(document).on('click', '#click_event', function(){
                  $(this).parent().next('ul').slideToggle('fast');
                });
                //Traitement du menu enfant
                $(document).on('click', '#click_event2', function(e){
                  $(this).parent().children('ul').slideToggle('fast');
                  e.stopPropagation();
                });
              });
            </script>
    </body>
</html>

Veuillez jouer avec CSS ci-dessous et concevez comme vous le souhaitez.

drop.css


span {
    display: block;
    margin: 0 0 4px 0;
    padding : 15px;
    line-height: 1;
    color :#fff;
    background: #5200b7;
    cursor :pointer;
}
  
li {
    cursor: pointer;
    border-bottom: 1px solid #5200b7;
    color: #222;
}

Une partie importante de cette implémentation est la création d'un "filtre de modèle personnalisé". La troisième ligne {% load Drop%} dans le fichier HTML est le processus de lecture du filtre de modèle personnalisé. Je n'expliquerai pas le filtre de modèle personnalisé en détail, mais j'ai créé mon propre filtre qui peut être utilisé dans le modèle Django. Tout ce que vous avez à faire est de créer un dossier "templatetags" dans votre projet et d'y créer un fichier de modèle personnalisé.

Ce qui suit est un fichier de modèle personnalisé.

Project_folder/templatetags/Drop.py


register = template.Library()

@register.filter
def in_category(things, category):    
    return things.filter(ParentCategoryID=category)

En tant que contenu de traitement, les données de base de données sont reçues dans le premier argument et CategoryID est reçu dans le deuxième argument. C'est aussi simple que de filtrer les données de base de données reçues par ParentCategoryID et de les renvoyer.

Comment utiliser est la 17e ligne du fichier html

python


{% for things in form_child|in_category:data.CategoryID %}

Un filtre de modèle personnalisé est appliqué aux données de base de données appelées form_child. Le CategoryID de CategoryIDModels est passé comme deuxième argument.

C'est un peu difficile à comprendre à ce rythme, alors jetons un coup d'œil aux données transmises au modèle dans views.py.

Mise en œuvre 3 (vues)

views.py


@login_required
def Dropmenu_date(request_val):
    ##Charger le modèle
    template = loader.get_template('Dropmenu.html')
    form = CategoryIDModels.objects.all().order_by('CategoryID')
    form_child = CategoryID2Models.objects.all().order_by('CategoryID')
    form_gchild = CategoryID3Models.objects.all().order_by('CategoryID')

    context = {
        'form': form,
        'form_child': form_child,
        'form_gchild': form_gchild,
    }

    return HttpResponse(template.render(context, request_val))

Après cela, si vous liez des vues et un modèle dans urls.py, un menu déroulant devrait s'afficher.

Recommended Posts

Implémentation du menu déroulant dans Django
[Django] Créer un menu déroulant
Implémentation de la fonction de connexion dans Django
Django
Implémentation du bouton like dans Django + Ajax
Blog Django sur heroku: implémentation de la connexion
Réagir → Ajax → Django sur les notes d'implémentation Linux
Implémentation du traitement asynchrone dans Django (Celery, Redis)