如何将 CreateView 与 ModelForm 一起使用

Posted

技术标签:

【中文标题】如何将 CreateView 与 ModelForm 一起使用【英文标题】:How do I use CreateView with a ModelForm 【发布时间】:2011-08-12 00:53:20 【问题描述】:

提交表单时,我的班级 AuthorCreateForm 出现错误。 名称错误 自我没有定义

如何使用 CreateForm?

我在我的 Author.py 文件中创建了一个类

from django.views.generic import TemplateView, ListView, CreateView
from books.models import Author, Publisher, Book
from books.forms import AuthorForm

class AuthorCreateView(CreateView):
    objAuthorForm = AuthorForm(self.request.POST)

    if(objAuthorForm.save()):
        success = "Form saved!"
    else:
        error = "There was an error!"

我有一个提交给 /Author/Create 的 html 模板

我的 urls.py 中有以下行

('^authors/create/$', Author.AuthorCreateView.as_view()),

我在此 URL 处呈现表单

('^authors/new/$', TemplateView.as_view(template_name="author_new.html")),

我发现基于类的视图令人困惑,有人有关于如何将其用于 CRUD 操作的好教程吗?

谢谢

【问题讨论】:

【参考方案1】:

您遇到的是 python 错误——self 未定义。 self 通常是指类方法上的类实例本身。

无论如何,我同意,这是全新的品牌,而不是记录在案的。我认为此时查看源代码绝对是关键。

为了适应基于类的视图,我先继承django.views.generic.base.View,它只实现几个方法,即尝试根据请求方法(post、get、head、-看源码)。

例如,这是用新视图类替换视图函数的第一步:

class MyClassBasedView(View):
    def get(self, request):
        # behave exactly like old style views
        # except this is called only on get request
        return http.HttpResponse("Get")

    def post(self, request):
        return http.HttpResponse("Post")

(r'^foobar/$', MyClassBasedView.as_view())

回到您的具体问题:

TemplateView.as_view() 所做的只是渲染模板 - CreateView 是处理 ModelForms 和模板渲染 (TemplateView) 的其他几个类的组合。

因此,举一个非常基本的例子,look to the docs 用于 mixins 的哪个类被 CreateView 使用。

我们看到它实现了TemplateResponseMixinModelFormMixinProcessFormView,每个都包含这些类的方法列表。


最基本的CreateView

在最基本的层面上,为CreateViewModelFormMixin提供模型或自定义ModelForm类as documented here.

您的 CreateView 类将如下所示

class AuthorCreateView(CreateView):
    form_class = AuthorForm
    template_name = 'author_new.html'
    success_url = 'success'

设置这 3 个核心属性后,在您的 URL 中调用它。

('^authors/create/$', Author.AuthorCreateView.as_view()),

渲染页面,您会看到您的 ModelForm 作为form 传递给模板,处理表单验证步骤(传入request.POST / 如果无效则重新渲染),以及调用form.save() 并重定向到success_url


开始重写类方法

要自定义行为,请开始覆盖为 mixins 记录的方法。

请记住,您只需像任何常规视图函数一样从这些方法之一返回 HttpResponse

覆盖form_invalid 的示例记录在ModelFormMixin 中:

class AuthorCreateView(CreateView):
    form_class = AuthorForm
    template_name = 'author_new.html'
    success_url = 'success'

    def form_invalid(self, form):
        return http.HttpResponse("form is invalid.. this is just an HttpResponse object")

随着表单变得越来越高级,这种按方法覆盖开始变得非常有用,最终让您可以用几行代码构建巨大的表单,只覆盖必要的部分。

假设您要传递表单自定义参数,例如 request 对象(如果您需要访问表单中的用户,这很常见):您只需要覆盖 get_form_kwargs

class MyFormView(FormView):
    def get_form_kwargs(self):
        # pass "user" keyword argument with the current user to your form
        kwargs = super(MyFormView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

基于类的视图是智能类使用的一个光辉例子。它给了我一个很好的介绍来构建我自己的视图和 python 类的混合。它节省了无数小时。

哇,这太长了。认为它开始只是文档评论的 URL :)

【讨论】:

类的组织方式真是太棒了!我不知道为什么我一开始就没有创建类视图。 如何解压forms.py 末尾的额外kwargs 的示例是here。

以上是关于如何将 CreateView 与 ModelForm 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

Django - 如何使用CreateView扩展自定义用户

在 Django 中,如何在提交 CreateView 时重定向到 UpdateView?

如何在 CreateView 中动态设置 ForeignKey 的初始值?

如何将引导类添加到模板中的 Django CreateView 表单字段?

如何覆盖 createView 以保存多个数据条目

将参数传递给 Django CreateView