I've looked through a few topics with questions almost the same as mine but none of them really helped. The thing is that I'm writing a training Django app where I'm storing info about music albums that I like. Currently I'm adding a form via which I want to add albums to the database (instead of the standard form within "/admin/"). So, the models I have are quite simple:
from django.db import models
class Genre(models.Model):
name = models.CharField(max_length=30)
class Meta:
verbose_name_plural = "genres"
def __str__(self):
return self.name
class Album(models.Model):
author = models.CharField(max_length=100)
name = models.CharField(max_length=100)
release_date = models.IntegerField()
cover = models.ImageField(upload_to="media")
genres = models.ManyToManyField("Genre", related_name="album")
def __str__(self):
return self.name
As you can see, Album and Genre classes are related to each other via ManyToManyField. The form responsible for adding an album to the database looks like this:
from django import forms
from .models import Genre
CHOICES = Genre.objects.all()
class AddAlbumForm(forms.Form):
author = forms.CharField(label="Album's author", max_length=100)
name = forms.CharField(label="Album's name", max_length=100)
release_date = forms.IntegerField(label="Album's release year")
genres = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=CHOICES)
cover = forms.FileField()
All in all, the form is operational, except for the line with "genres" variable (if I comment it, the form works just fine). The related view looks like this:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.paginator import Paginator
from albums.models import Album, Genre
from albums.forms import AddAlbumForm
def add_album(request):
if request.method == "POST":
form = AddAlbumForm(request.POST, request.FILES)
if form.is_valid():
album = Album()
album.name = form.cleaned_data.get("name")
album.author = form.cleaned_data.get("author")
album.release_date = form.cleaned_data.get("release_date")
album.cover = form.cleaned_data.get("cover")
album.genres = form.cleaned_data.get("genres")
album.save()
return HttpResponseRedirect("/")
else:
form = AddAlbumForm()
return render(request, "albums/add_album.html", {"form": form})
And finally, the template of the form looks like this:
{% extends "base.html" %}
{% block page_title %}
<h2>Add an album: </h2>
{% endblock page_title %}
{% block page_content %}
<form action="/add_album/" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="Submit"></p>
</form>
{% endblock page_content %}
As for the urls, I won't publish the related code since my problem isn't connected to this issue. So, when I try to access the url with the form, I get the following error:
TypeError at /add_album/ Cannot unpack non-iterable Genre object
I want all of the genres to choose from to be displayed in the form so a user could choose multiple options and save them as 'genre' attribute of a related album.
What am I doing wrong, guys? Any help would be greatly appreciated!
try this
you are trying to pass queryset in as choices, which will not work.
refer this
https://docs.djangoproject.com/en/5.0/ref/forms/fields/#fields-which-handle-relationships