how can i show many-to-mant-field objects in a form?

Question:

hi i wrote a code to make genre section in site and i used many-to-many-field in models to add it:

from django.db import models
from django.contrib.auth.models import User


class Genre(models.Model):
    name = models.CharField(unique=True,max_length=20)

    def __str__(self):
        return self.name.title()



class Mdata(models.Model):
    name = models.CharField(max_length=100)
    artist = models.CharField(max_length=150)
    album = models.CharField(max_length=100)
    nation = models.CharField(max_length=100)
    duration = models.DecimalField(max_digits=4,decimal_places=2)
    released_in = models.DecimalField(max_digits=4,decimal_places=0)
    uploaded_at = models.DateTimeField(auto_now_add=True)
    image = models.ImageField(upload_to='images/',blank=True,null=True)
    audio = models.FileField(upload_to='audios/',null=True,blank=True)
    genre = models.ManyToManyField(Genre)
    uploader = models.ForeignKey(User,on_delete=models.CASCADE)

    def __str__(self):
        return self.name.title()+" by "+self.artist.title()

but when i check music itself in site it just show how many object I’ve selected not genre’s as you can see here:

[![screen shot][1]: https://i.stack.imgur.com/xHaMK.png

here’s my template:

{% extends 'pages/base.html' %}

{% block content %}

<form>
    {% if mdata.image %}
        <img src="mdata.image.url" height="500" width="500">
    {% endif %}

    {% for field in form %}
        <p>{{ field.label }} : {{ field.value}}</p>
    {% endfor %}
</form>

<a href="{% url 'pages:edit_music' mdata.id %}">edit</a>

{% endblock %}

and forms(forms is simple i just added models as field):

from django import forms
from django.forms import ModelForm
from .models import Mdata


class MdataForm(ModelForm):
    class Meta:
        model = Mdata
        fields =[
            'name',
            'artist',
            'album',
            'genre',
            'nation',
            'duration',
            'released_in',
            'image',
            'audio',
            ]
Asked By: Nicolas_Darksoul

||

Answers:

Django’s many-to-many field renders to a <select multiple> by default. {{ field.value }} returns a list of id. Thus [1] in your screenshot means your MData here has one Genre and its id is 1.

If you want to display names of Genre in the list, change your form to

from django import forms
from .models import MData, Genre

class MDataForm(forms.ModelForm):
    genre = forms.ModelMultipleChoiceField(Genre, to_field_name='name')
    class Meta:
        model = MData
        fields = [
            'name',
            'artist',
            'album',
            'genre',
            'nation',
            'duration',
            'released_in',
            'image',
            'audio',
        ]

Also don’t forget to surround data.image.url with {{ and }}.

Answered By: Ezon Zhao