Reputation: 13178
I have a class Book
:
from django.db import models
from users.models import User
class Book(models.Model):
title = models.CharField(max_length=150)
authors = models.ManyToManyField("Author")
which links to the Author class:
class Author(models.Model):
name = models.CharField(max_length=150)
birthday = models.DateField()
And I have a form for the Book class called BookForm
from django import forms
from django.forms import CharField
from books.models import Book
class BookForm(forms.ModelForm):
authors = CharField()
class Meta:
model = Book
fields = ["title","authors"]
I want to create Books with the BookForm which is simple enough, but instead of picking the authors from a list like would happen with the default (since it is a ManyToManyField), I want the user to be able to enter text, a comma separated string of each author's name. My view is set up like so:
def create_book(request):
if request.user is None:
return redirect("/users/login/")
if request.method == "POST":
form = BookForm(request.POST)
if form.is_valid():
nbook = form.save(commit=False)
authorlist = form.authors.split(",")
nbook.owner = request.user
nbook.save()
for auth in authorlist:
nbook.authors.create(name=auth)
return redirect("/books/")
else:
form = BookForm()
return render_to_response("books/create.html", {
"form": form,
}, context_instance=RequestContext(request))
But this does not work. I get the error 'BookForm' object has no attribute 'authors'
. I'm not sure if there is a fundamental problem here or if its just syntax, but can someone please lend a hand? I am completely new to both Python and Django :[
Thanks!
Upvotes: 3
Views: 5761
Reputation: 3808
To stop django automaticly creating the <select>
form entry, remove the 'authors'
from the fields list:
class BookForm(forms.ModelForm):
authors = CharField()
class Meta:
model = Book
fields = ["title"]
Django was overriding the authors entry that you created with the one it automatically created.
As for your second error, the correct way to get data from a bound form would not be via form.authors
, but from form.cleaned_data['authors']
.
P.S. You start with this:
if request.user is None:
return redirect("/users/login/")
For this you should use the login_required
decorator.
Upvotes: 2