Alexunder
Alexunder

Reputation: 25

ManyToManyField returns empty string in template

So I have these 2 models. My Course model is linked with a ManytoMany field to TeacherData. When I try to render teacher in a template, no result appears. What is wrong ?

class TeacherData(models.Model):
    name = models.CharField(max_length=30)
    surname = models.CharField(max_length=50)
    teacher_ID = models.CharField(unique=True, max_length=14)
    notes = models.CharField(max_length=255, default=None, blank=True)

    class Meta:
        verbose_name = "Teacher Data"
        verbose_name_plural = "Teachers Data"

    def __str__(self):
        return self.surname

class Course(models.Model):
    study_programme = models.ForeignKey('StudyProgramme', on_delete=models.CASCADE, default='')
    name = models.CharField(max_length=50, unique=True)
    ects = models.PositiveSmallIntegerField(validators=[MaxValueValidator(99)])
    description = models.TextField()
    year = models.PositiveSmallIntegerField(validators=[MaxValueValidator(99)])
    semester = models.IntegerField(choices=((1, "1"),
                                            (2, "2"),
                                            ), default=None)
    teacher = models.ManyToManyField('TeacherData', verbose_name="Taught By")
    slug = models.SlugField(max_length=140, unique=True)

    def __str__(self):
        return self.name
<ul>
        {% for c in courses.all %}
            <li>{{ c.study_programme }}</li>
            <li>{{ c.name }}</li>
            <li>{{ c.ects }}</li>
            <li>{{ c.description }}</li>
            <li>{{ c.year }}</li>
            <li>{{ c.semester }}</li>
            <li>{{ c.teacher }}</li>
        {% endfor %}
    </ul>
def courses(request, slug):
    query = Course.objects.get(slug=slug)
    context = {'courses': Course.objects.filter(slug=slug),
               'lectures': query.lectures.order_by('lecture_category'),
               }
    return render(request, 'courses/courses.html', context)

Upvotes: 0

Views: 84

Answers (1)

ascripter
ascripter

Reputation: 6223

In your template, c.teacher will be Django's ManyToMany-Manager (like Course.objects is a Manager). I suppose this will just be rendered to an empty string. Try c.teacher.all instead. This will give you the QuerySet of all teachers associated with the course.

If you need a more granular template, here's the principal structure:

<ul>
    {% for c in courses.all %}
        <li>{{ c.study_programme }}</li>
        <li>{{ c.name }}</li>
        <li>{{ c.ects }}</li>
        <li>{{ c.description }}</li>
        <li>{{ c.year }}</li>
        <li>{{ c.semester }}</li>
        <li><ul>
            {% for t in c.teacher.all %}
                <li>{{ t.name }} {# or whatever else you want to display #}</li>
            {% endfor %}
        </ul></li>
    {% endfor %}
</ul>

One more sidenote: Since Course to Teacher is M2M, it would be more convenient (and common practice) to give the field a plural name: Course.teachers

Upvotes: 1

Related Questions