RandomNumberFun
RandomNumberFun

Reputation: 642

How should I iterate over this dictionary of objects in this Django Template?

I have the below view.

def select_classes(request):
 ...
            classesBySelectedGrade = courseBlock.objects.filter(grades__grade__contains=form['grade'].value()).order_by(
                'time')
            classOptionCount = classesBySelectedGrade.all().count()    

            classOptionDict = {}    

            for i in range(classOptionCount):
                classOptionDict["option " + str(i + 1)] = classesBySelectedGrade    

    return render(request, 'select-classes.html', {'classesOptions': classOptionDict})

The goal of the above view:

  1. Is to take a set of "courses" sorted by time.
  2. Create a copy of the set of course nth many times as courses.count()
  3. Add each copy to a dictionary
  4. Pass this dictionary to my template.

Here is the data that is being passed.

 {
     'classesOptions': {
         'option 1': < QuerySet[ < courseBlock: Course Block: Some Course Block 1 - Start: 07: 00: 00, Endtime: 08: 00: 00: > , < courseBlock: Course Block: Some Course Block 2 - Start: 07: 00: 00, Endtime: 08: 00: 00: > ] > ,
         'option 2': < QuerySet[ < courseBlock: Course Block: Some Course Block 1 - Start: 07: 00: 00, Endtime: 08: 00: 00: > , < courseBlock: Course Block: Some Course Block 2 - Start: 07: 00: 00, Endtime: 08: 00: 00: > ] >
     }
 }

My current goal in my template:

  1. To iterate over passed in dictionary to read the values out.

Here is the current loop I am using.

{% for classesOption in classesOptions %}

    <p>
        {{ classesOption }}

        {% for classes in classesOption %}

            {{ classes }}

        {% endfor %}

    </p>

{% endfor %}

And this is my output.

option 2 o p t i o n 2
option 1 o p t i o n 1

The above output is expected with the particular data I am testing. That is I am expecting 2 copies in this test case.

For more context here are my models:

class Course(models.Model):
    title = models.CharField(max_length=200)
    limit = models.IntegerField(default=10)
    description = models.TextField(max_length=800)
    location = models.CharField(max_length=200, default="")
    teachers = models.TextField(max_length=800, default="")

class startEndTime(models.Model):
    endTime = models.TimeField()
    startTime = models.TimeField()

class courseBlock(models.Model):
    course = models.ManyToManyField(Course, related_name='course_in_block')
    grades = models.ManyToManyField(Grade, related_name='name_in_block')
    title = models.CharField(max_length=100)
    time = models.ForeignKey(startEndTime, on_delete=models.CASCADE)

Upvotes: 0

Views: 1227

Answers (1)

knbk
knbk

Reputation: 53699

Iterating over a dict in Python (and by extension, Django's template language) will iterate over the keys, not the values. You are then iterating over the key, which is a string. Iterating over a string will return the individual characters.

In this case it seems you want to print the key and then iterate over the value. You can use the dict.items method to iterate over the keys and the values at the same time:

{% for option, classes in classesOptions.items %}
    <p>
        {{ option }}
        {% for class in classes %}
            {{ class }}
        {% endfor %}
    </p>
{% endfor %}

Upvotes: 2

Related Questions