首页 > 其他分享 >django 1.8 官方文档翻译: 3-4-3 使用基于类的视图处理表单

django 1.8 官方文档翻译: 3-4-3 使用基于类的视图处理表单

时间:2023-04-13 14:37:31浏览次数:43  
标签:name form self 1.8 视图 表单 import django class


使用基于类的视图处理表单

表单的处理通常有3 个步骤:

  • 初始的的GET (空白或预填充的表单)
  • 带有非法数据的POST(通常重新显示表单和错误信息)
  • 带有合法数据的POST(处理数据并重定向)

你自己实现这些功能经常导致许多重复的样本代码(参见在视图中使用表单)。为了避免这点,Django 提供一系列的通用的基于类的视图用于表单的处理。

基本的表单

根据一个简单的联系人表单:

#forms.py

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField()
    message = forms.CharField(widget=forms.Textarea)

    def send_email(self):
        # send email using the self.cleaned_data dictionary
        pass

可以使用FormView来构造其视图:

#views.py

from myapp.forms import ContactForm
from django.views.generic.edit import FormView

class ContactView(FormView):
    template_name = 'contact.html'
    form_class = ContactForm
    success_url = '/thanks/'

    def form_valid(self, form):
        # This method is called when valid form data has been POSTed.
        # It should return an HttpResponse.
        form.send_email()
        return super(ContactView, self).form_valid(form)

注:

  • FormView继承TemplateResponseMixin所以这里可以使用template_name
  • form_valid()的默认实现只是简单地重定向到success_url

模型的表单

通用视图在于模型一起工作时会真正光芒四射。这些通用的视图将自动创建一个ModelForm,只要它们能知道使用哪一个模型类:

  • 如果给出model属性,则使用该模型类。
  • 如果get_object() 返回一个对象,则使用该对象的类。
  • 如果给出queryset,则使用该查询集的模型。

模型表单提供一个form_valid() 的实现,它自动保存模型。如果你有特殊的需求,可以覆盖它;参见下面的例子。

你甚至不需要为CreateViewUpdateView提供success_url —— 如果存在它们将使用模型对象的get_absolute_url()

如果你想使用一个自定义的ModelForm(例如添加额外的验证),只需简单地在你的视图上设置form_class

当指定一个自定义的表单类时,你必须指定模型,即使form_class 可能是一个ModelForm

首先我们需要添加get_absolute_url() 到我们的Author 类中:

#models.py

from django.core.urlresolvers import reverse
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=200)

    def get_absolute_url(self):
        return reverse('author-detail', kwargs={'pk': self.pk})

然后我们可以使用CreateView 机器伙伴来做实际的工作。注意这里我们是如何配置通用的基于类的视图的;我们自己没有写任何逻辑:

#views.py

from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.core.urlresolvers import reverse_lazy
from myapp.models import Author

class AuthorCreate(CreateView):
    model = Author
    fields = ['name']

class AuthorUpdate(UpdateView):
    model = Author
    fields = ['name']

class AuthorDelete(DeleteView):
    model = Author
    success_url = reverse_lazy('author-list')

这里我们必须使用reverse_lazy() 而不是reverse,因为在该文件导入时URL 还没有加载。

fields 属性的工作方式与ModelForm 的内部Meta类的fields 属性相同。除非你用另外一种方式定义表单类,该属性是必须的,如果没有将引发一个ImproperlyConfigured 异常。

如果你同时指定fieldsform_class 属性,将引发一个ImproperlyConfigured 异常。

Changed in Django 1.8:

省略fields 属性在以前是允许的,但是导致表单带有模型的所有字段。
Changed in Django 1.8:

以前,如果fields 和form_class 两个都指定,会默默地忽略 fields。

最后,我我们来将这些新的视图放到URLconf 中:

#urls.py

from django.conf.urls import url
from myapp.views import AuthorCreate, AuthorUpdate, AuthorDelete

urlpatterns = [
    # ...
    url(r'author/add/$', AuthorCreate.as_view(), name='author_add'),
    url(r'author/(?P<pk>[0-9]+)/$', AuthorUpdate.as_view(), name='author_update'),
    url(r'author/(?P<pk>[0-9]+)/delete/$', AuthorDelete.as_view(), name='author_delete'),
]

这些表单继承SingleObjectTemplateResponseMixin,它使用template_name_suffix并基于模型来构造template_name

在这个例子中:

  • CreateViewUpdateView 使用 myapp/author_form.html
  • DeleteView 使用 myapp/author_confirm_delete.html

如果你希望分开CreateViewUpdateView 的模板,你可以设置你的视图类的template_nametemplate_name_suffix

模型和request.user

为了跟踪使用CreateView 创建一个对象的用户,你可以使用一个自定义的ModelForm 来实现这点。首先,向模型添加外键关联:

#models.py

from django.contrib.auth.models import User
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=200)
    created_by = models.ForeignKey(User)

    # ...

在这个视图中,请确保你没有将created_by 包含进要编辑的字段列表,并覆盖form_valid() 来添加这个用户:

#views.py

from django.views.generic.edit import CreateView
from myapp.models import Author

class AuthorCreate(CreateView):
    model = Author
    fields = ['name']

    def form_valid(self, form):
        form.instance.created_by = self.request.user
        return super(AuthorCreate, self).form_valid(form)

注意,你需要使用login_required() 来装饰这个视图,或者在form_valid() 中处理未认证的用户。

AJAX 示例

下面是一个简单的实例,展示你可以如何实现一个表单,使它可以同时为AJAX 请求和‘普通的’表单POST 工作:

from django.http import JsonResponse
from django.views.generic.edit import CreateView
from myapp.models import Author

class AjaxableResponseMixin(object):
    """
    Mixin to add AJAX support to a form.
    Must be used with an object-based FormView (e.g. CreateView)
    """
    def form_invalid(self, form):
        response = super(AjaxableResponseMixin, self).form_invalid(form)
        if self.request.is_ajax():
            return JsonResponse(form.errors, status=400)
        else:
            return response

    def form_valid(self, form):
        # We make sure to call the parent's form_valid() method because
        # it might do some processing (in the case of CreateView, it will
        # call form.save() for example).
        response = super(AjaxableResponseMixin, self).form_valid(form)
        if self.request.is_ajax():
            data = {
                'pk': self.object.pk,
            }
            return JsonResponse(data)
        else:
            return response

class AuthorCreate(AjaxableResponseMixin, CreateView):
    model = Author
    fields = ['name']

译者:Django 文档协作翻译小组,原文:Built-in editing views

本文以 CC BY-NC-SA 3.0 协议发布,转载请保留作者署名和文章出处。

Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。

标签:name,form,self,1.8,视图,表单,import,django,class
From: https://blog.51cto.com/wizardforcel/6187978

相关文章

  • django 1.8 官方文档翻译: 3-4-1 基于类的视图
    基于类的视图视图是一个可调用对象,它接收一个请求然后返回一个响应。这个可调用对象可以不只是函数,Django提供一些可以用作视图的类。它们允许你结构化你的视图并且利用继承和混合重用代码。后面我们将介绍一些用于简单任务的通用视图,但你可能想要设计自己的可重用视图的结构以适......
  • django 1.8 官方文档翻译: 3-2-1 内建的视图
    内建的视图有几个Django的内建视图在编写视图中讲述,文档的其它地方也会有所讲述。开发环境中的文件服务器static.serve(request,path,document_root,show_indexes=False)在本地的开发环境中,除了你的项目中的静态文件,可能还有一些文件,出于方便,你希望让Django来作为服务器。ser......
  • django 1.8 官方文档翻译: 3-1-4 视图装饰器
    视图装饰器Django为视图提供了数个装饰器,用以支持相关的HTTP服务。允许的HTTP方法django.views.decorators.http包里的装饰器可以基于请求的方法来限制对视图的访问。若条件不满足会返回django.http.HttpResponseNotAllowed。require_http_methods(request_method_list)[source]......
  • django 1.8 官方文档翻译: 3-1-3 Django 的快捷函数
    Django的快捷函数django.shortcuts收集了“跨越”多层MVC的辅助函数和类。换句话讲,这些函数/类为了方便,引入了可控的耦合。renderrender(request,template_name[,context][,context_instance][,content_type][,status][,current_app][,dirs][,using])[source]结合一个......
  • django 1.8 官方文档翻译: 6-4-2 编写自定义的django-admin命令
    编写自定义的django-admin命令应用可以通过manage.py注册它们自己的动作。例如,你可能想为你正在发布的Django应用添加一个manage.py动作。在本页文档中,我们将为教程中的polls应用构建一个自定义的closepoll命令。要做到这点,只需向该应用添加一个management/commands目录。Django......
  • django 1.8 官方文档翻译: 6-6-2 如何使用WSGI 部署
    如何使用WSGI部署Django首要的部署平台是WSGI,它是PythonWeb服务器和应用的标准。Django的startproject管理命名为你设置一个简单的默认WSGI配置,你可以根据你项目的需要做调整并指定任何与WSGI兼容的应用服务器使用。Django包含以下WSGI服务器的入门文档:如何使用Apache和......
  • django 1.8 官方文档翻译:6-5-1 Django中的测试
    Django中的测试自动化测试对于现代web开发者来说,是非常实用的除错工具。你可以使用一系列测试–测试套件–来解决或者避免大量问题:当你编写新代码的时候,你可以使用测试来验证你的代码是否像预期一样工作。当你重构或者修改旧代码的时候,你可以使用测试来确保你的修改不会在意料之......
  • django 1.8 官方文档翻译:2-5-9 条件表达式
    条件表达式NewinDjango1.8.条件表达式允许你在过滤器、注解、聚合和更新操作中使用if...elif...else的逻辑。条件表达式为表中的每一行计算一系列的条件,并且返回匹配到的结果表达式。条件表达式也可以像其它表达式一样混合和嵌套。条件表达式类我们会在后面的例子中使用下......
  • django 1.8 官方文档翻译: 2-5-7 自定义查找
    自定义查找NewinDjango1.7.Django为过滤提供了大量的内建的查找(例如,exact和icontains)。这篇文档阐述了如何编写自定义查找,以及如何修改现存查找的功能。关于查找的API参考,详见查找API参考。一个简单的查找示例让我们从一个简单的自定义查找开始。我们会编写一个自定义查找ne,提供......
  • django 1.8 官方文档翻译: 2-5-10 数据库函数
    数据库函数NewinDjango1.8.下面记述的类为用户提供了一些方法,来在Django中使用底层数据库提供的函数用于注解、聚合或者过滤器等操作。函数也是表达式,所以可以像聚合函数一样混合使用它们。我们会在每个函数的实例中使用下面的模型:classAuthor(models.Model):name=model......