arcee123
arcee123

Reputation: 243

Grouping in Django View

I am trying to group a table output by one of it's columns. Below is the model (yes, this is a star trek-themed site I'm building...learning django on the way):

class ShipClass (models.Model):
    ALLEGIENCE_CHOICES = (
    ('FED', 'Federation'),
    ('KGE', 'Klingon Empire'),
    ('RSE', 'Romulan Star Empire')
    )
    Origin = models.CharField(max_length=3, choices=ALLEGIENCE_CHOICES, default='FED')
    ClassName = models.CharField(max_length=20)
    NumberOfCrew = models.IntegerField()

    def __str__(self):
        return self.ClassName

    class Meta:
        unique_together = ("Origin", "ClassName")

What I'm trying to do is output the view of this model in such a way that the list appears to be grouped by it's Allegiance choice. How do I perform grouping in the template-level?

such as

Thanks.

Upvotes: 0

Views: 365

Answers (2)

sax
sax

Reputation: 3806

you can use ifchanged

 qs = ShipClass.objects.order_by("Origin", "Classname")


 {% for entry in qs %}
    {% ifchanged entry.Origin %}
       {{ entry.Origin }}
    {% endifchanged %}
    {{ entry.Classname }}
 {% endfor %}

Upvotes: 1

brobas
brobas

Reputation: 606

in your view you can build a dictionary whose keys are the allegiance names and values are the list of classNames for that allegiance. To get the keys you can first access your model's choices and then loop through each to make a filter query to get the corresponding className lists, something like:

starship_classes_by_allegiance = {}
for choice in ShipClass._meta.get_field('Origin').choices:  
    allegiance_id, allegiance_label = choice
    starship_classes_by_allegiance[allegiance_label] = ShipClass.objects.filter(Origin=allegiance_id).values('ClassName').distinct()

then you can iterate over this dict in your template like:

{% for allegiance_label in starship_classes_by_allegiance %}

    {{ allegiance_label }}

    <ul>
    {% for class_name in starship_classes_by_allegiance.allegiance_label %}

        <li>{{ class_name }}</li>

    {% endfor %}
    </ul>

{% endfor %}

Upvotes: 0

Related Questions