Joseph
Joseph

Reputation: 13178

Django: Changing a field type in a model form and then applying it to the model class

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

Answers (1)

Blue Peppers
Blue Peppers

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

Related Questions