Django:在模型表单中更改字段类型并应用于模型类

3 投票
1 回答
5730 浏览
提问于 2025-04-16 07:46

我有一个类叫做 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")

这个类和一个叫做 Author 的类有关联:

class Author(models.Model):
    name = models.CharField(max_length=150)
    birthday = models.DateField()

我还有一个用于 Book 类的表单,叫做 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"]

我想用这个 BookForm 来创建书籍,这个过程其实挺简单的。不过,我不想让用户从一个列表中选择作者(因为这是一个多对多的关系),而是希望用户可以输入文本,输入每个作者的名字,用逗号分隔开。我的视图设置成这样:

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))

但是这样并不奏效。我遇到了一个错误,提示 'BookForm' object has no attribute 'authors'。我不确定这是一个根本性的问题,还是只是语法上的错误,但能不能请大家帮帮我?我对 Python 和 Django 完全是新手 :[

谢谢!

1 个回答

2

要停止Django自动创建的<select>表单项,你需要从字段列表中移除'authors'

class BookForm(forms.ModelForm):
    authors = CharField()
    class Meta:
        model = Book
        fields = ["title"]

Django会用它自动创建的内容覆盖你自己创建的作者项。

至于你的第二个错误,正确获取绑定表单数据的方法不是用form.authors,而是用form.cleaned_data['authors']

另外,你可以从这里开始:

if request.user is None:
    return redirect("/users/login/")

为此,你应该使用login_required装饰器。

撰写回答