2
votes

Comment imbriquer les sous-catégories juste sous la catégorie parent pendant le rendu

Je veux que les sous-catégories de chacun de mes objets de catégorie soient rendues sous forme de menu déroulant imbriqué dans sa catégorie parente. J'ai du mal à mettre cela en œuvre. Comment ça marche?

Voici mes modèles de catégorie et de sous-catégorie:

{% for category in categories %}
    <div class="nav-item dropdown">
        <a href="#" class="py-3 nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            {{ category.name }}
        </a>
        <div class="dropdown-menu rounded-0">

            {% for sub_category in sub_categories %}
            <a class="dropdown-item" href="#">
                {{ sub_category.name }}
            </a>
            {% endfor %}

        </div>
    </div>
{% endfor %}

Voici ma fonction d'affichage:

def home(request):
    categories = Category.objects.all()
    #sub_categories = I don't know how
    context = {
        'categories': categories,
        #'sub_categories': sub_categories
    }

    return render(request, 'blog/home.html', context)

Ceci est à l'intérieur de mon modèle:

class Category(models.Model):
    name = models.CharField(max_length=32)


class SubCategory(models.Model):
    name = models.CharField(max_length=50)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

Les catégories sont bien rendues, mon problème est avec les sous-catégories.


2 commentaires

Quel est le problème avec les sous-catégories?


Nevermind, je pense que je comprends ce que tu veux dire.


3 Réponses :


0
votes

Cette méthode ne nécessite aucune modification de vos modèles.

Ce que j'ai dû faire dans des cas comme celui-ci, c'est de regrouper les catégories et les sous-catégories dans une seule structure de données, puis de transmettre tout cela au modèle.

Voici du code pour un autre projet que j'ai réalisé. J'associais une étude à sa liste de participants.

{% for participants, study in studies %}
    {{study.title}}
            {% for part in participants %}
                <p>{{part.info}}</p>

                {% endfor %}
{% endfor %}

        participants = []
        try:
            studies = Study.objects.filter(investigators=Researcher.objects.get(user_id=request.user.id))
        except (Study.DoesNotExist, Researcher.DoesNotExist) as e:
            studies = []
        participantList = []
        for study in studies:
                participantList = Approval.objects.filter(study=study)
                if (len(participantList) == 0 ):
                    participants.append([[], study])
                elif (len(participantList) == 1 ):
                    participants.append([participantList, study])
    return render(request, 'manage.html',{'studies':participants, 'profile': user_profile})

La clé est essentiellement de coupler les informations requises dans une liste, puis de les itérer ensemble dans le modèle pour éviter le problème de la boucle for.

Comme vous n'associez pas des modèles avec des modèles, vous pouvez simplement remplacer participantList = Approval.objects.filter (study = study) et tout cela par un appel à un dict par le nom de la catégorie principale comme argument.


1 commentaires

Soyez gentil et vérifiez ma question mise à jour, regardez comment j'ai modélisé ma catégorie et ma sous-catégorie



0
votes

Votre modèle de sous-catégories doit être lié d'une manière ou d'une autre au modèle de catégories. Vous devriez avoir quelque chose comme ceci dans votre modèle de sous-catégories:

{% for category in categories %}
    <div class="nav-item dropdown">
        <a href="#" class="py-3 nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            {{ category.name }}
        </a>
        <div class="dropdown-menu rounded-0">

            {% for sub_category in category.sub_categories.all %}
            <a class="dropdown-item" href="#">
                {{ sub_category.name }}
            </a>
            {% endfor %}

        </div>
    </div>
{% endfor %}

Vous pouvez le faire sur vos vues.py:

def home(request):
    categories = Category.objects.all().order_by('-date_posted')
    context = {
        'categories': categories,
    }

    return render(request, 'blog/home.html', context)

Et dans votre template, vous pouvez le faire:

class Sub_categories(models.Model):    
    category = models.OneToOneField(Category, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, null=True)

Je suppose que vous pouvez également utiliser un ManyToManyField dans votre modèle de catégorie pour rendre le modèle de catégorie lié à celui de la sous-catégorie.

p>


0 commentaires

0
votes

Pour créer des modèles de sous-catégories ...

Category(models.Model):
    name = models.Charfield()

Sub_Category(models.Model):
    name = models.CharField()
    category = models.ManyTOManyField(Sub_Category)

def home(request):
    categories = Category.objects.all().order_by('-date_posted')

    cid = #Generate your Category id single or list...

    //you can ever it multiple time with for loop...
    sub_categories = Sub_Category.objects.filter(category=cid) 
    context = {
        'categories': categories,
        'sub_categories': sub_categories
    }

    return render(request, 'blog/home.html', context)


0 commentaires