ManyToMany and Template

Hi guys,

I started recently to use Django, I’m having an issue to display information on my template using a ManToMany relationship.

I’m trying to display actors that played on a specific movies, and only display the top 5 actors (order < 5)

I managed to do it for simple case, but first time with this relationship.

Thanks for your help.

{% for lines in roles %}

Acteur: {{ lines.name }}

Rôle: {{ lines.role }}

  {% endfor %}

def movie_detail(request, id):
movie = Movie.objects.get(id=id)
role_list = Role.objects.filter(order__range=(0, 5))
return render(request, ‘bms/visitor/film.html’, {‘movies’: movie}

class Movie(models.Model):
title = models.CharField(max_length=45, verbose_name=‘Titre’)
release_date = models.DateField(blank=True, null=True, verbose_name=‘Publication’)
categorie_list = models.ForeignKey(Categorie, on_delete=models.CASCADE, verbose_name=‘Genre’)
production_list = models.ForeignKey(Production_company, null=True, on_delete=models.CASCADE, verbose_name=‘Société de production’)
image = models.ImageField(upload_to=‘bms/photos’, null=True)
synopsis = models.TextField(blank=True, null=True, verbose_name=‘Résumé’)
duration = models.IntegerField(blank=True, null=True, verbose_name=‘Durée’)
is_available_in_theaters = models.BooleanField(default=0, verbose_name=‘Au cinéma’)
review_list = models.ManyToManyField(Review, blank=True)

class Meta:
    verbose_name = "Film"
    ordering = ['title']

def __str__(self):
    return '{}'.format(self.title)

class Actor(models.Model):
name = models.CharField(max_length=45)
birth_date = models.DateField(null=True)
place_birth = models.CharField(max_length=60, null=True)
image = models.ImageField(upload_to=‘bms/photos/actor’, null=True)
biography = models.TextField(blank=True, null=True, default=‘Non disponible’, verbose_name=‘Biographie’)
movie_list = models.ManyToManyField(Movie, through=‘Role’, related_name=‘actors’)

class Meta:
    verbose_name = "Acteurs"
    ordering = ['name']

def __str__(self):
    return '{}'.format(self.name)

class Role(models.Model):
actor = models.ForeignKey(Actor, on_delete=models.CASCADE)
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
role = models.CharField(max_length=80, null=True)
name = models.CharField(max_length=45)
order = models.IntegerField(null=True)

class Role:
    verbose_name = "Role"
    ordering = ['role']

def __str__(self):
    return '{} {}'.format(self.role, self.name)

Hi, @yannlm.

If I get it right, given your current structure I think you can accomplish this by changing your view:

def movie_detail(request, id):
    movie = Movie.objects.get(id=id)
    roles = Role.objects.filter(movie=movie).order_by('order')[:5]
    return render(request, 'bms/visitor/film.html', {'roles': roles})

There’s probably a “more djangonaut way” of doing this, but I hope that at least it shows what you want.

You could write it as:

    movie = Movie.objects.get(id=id)
    roles = movie.role_set.order_by('order')[:5]

if you wanted to be more concise.