在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 使用基于類的視圖處理表單
點(diǎn)擊劫持保護(hù)
安全問題歸檔
Model 類參考
將遺留數(shù)據(jù)庫整合到Django
關(guān)聯(lián)對(duì)象參考
內(nèi)建基于類的視圖的API
聚合
Django 中的用戶認(rèn)證
django.contrib.humanize
Django管理文檔生成器
分頁
使用Django輸出CSV
加密簽名
文件儲(chǔ)存API
安全
Django中的測(cè)試
國(guó)際化和本地化
為Django編寫首個(gè)補(bǔ)丁
條件表達(dá)式
日志
模型元選項(xiàng)
部署靜態(tài)文件
執(zhí)行查詢
使用Django認(rèn)證系統(tǒng)
基于類的視圖
中間件
編寫自定義的django-admin命令
Django 的設(shè)置
格式本地化
數(shù)據(jù)庫訪問優(yōu)化
錯(cuò)誤報(bào)告
基于類的內(nèi)建通用視圖
編寫自定義存儲(chǔ)系統(tǒng)
編寫你的第一個(gè) Django 程序 第3部分
編寫數(shù)據(jù)庫遷移
使用表單
編寫你的第一個(gè) Django 程序 第2部分
編寫你的第一個(gè) Django 程序 第1部分
如何使用會(huì)話
系統(tǒng)檢查框架
新手入門
信號(hào)
編寫視圖
如何使用WSGI 部署
編寫你的第一個(gè)Django應(yīng)用,第6部分
常見的網(wǎng)站應(yīng)用工具
Widgets
內(nèi)建的視圖
模型實(shí)例參考
視圖層
Django中的密碼管理
高級(jí)教程:如何編寫可重用的應(yīng)用
國(guó)際化和本地化
"本地特色"附加功能
TemplateResponse 和 SimpleTemplateResponse
模式編輯器
文件上傳
快速安裝指南
部署 Django
表單 API
表單素材 ( <code>Media</code> 類)
管理文件
其它核心功能
查找 API 參考
表單
Admin
數(shù)據(jù)庫函數(shù)
自定義查找
使用基于類的視圖處理表單
管理操作
開發(fā)過程
編寫你的第一個(gè)Django應(yīng)用,第5部分
進(jìn)行原始的sql查詢
模型層
多數(shù)據(jù)庫
編寫你的第一個(gè) Django 程序 第4部分
Django安全
Django 初探
Django異常
重定向應(yīng)用
按需內(nèi)容處理
管理器
視圖裝飾器
驗(yàn)證器
使用Django輸出PDF
File對(duì)象
Django 的快捷函數(shù)
基于類的通用視圖 —— 索引
為模型提供初始數(shù)據(jù)
模板層
URL調(diào)度器
中間件
模型

使用基于類的視圖處理表單

表單的處理通常有3 個(gè)步驟:

  • 初始的的GET (空白或預(yù)填充的表單)
  • 帶有非法數(shù)據(jù)的POST(通常重新顯示表單和錯(cuò)誤信息)
  • 帶有合法數(shù)據(jù)的POST(處理數(shù)據(jù)并重定向)

你自己實(shí)現(xiàn)這些功能經(jīng)常導(dǎo)致許多重復(fù)的樣本代碼(參見在視圖中使用表單)。為了避免這點(diǎn),Django 提供一系列的通用的基于類的視圖用于表單的處理。

基本的表單

根據(jù)一個(gè)簡(jiǎn)單的聯(lián)系人表單:

#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來構(gòu)造其視圖:

#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()的默認(rèn)實(shí)現(xiàn)只是簡(jiǎn)單地重定向到success_url。

模型的表單

通用視圖在于模型一起工作時(shí)會(huì)真正光芒四射。這些通用的視圖將自動(dòng)創(chuàng)建一個(gè)ModelForm,只要它們能知道使用哪一個(gè)模型類:

  • 如果給出model屬性,則使用該模型類。
  • 如果get_object() 返回一個(gè)對(duì)象,則使用該對(duì)象的類。
  • 如果給出queryset,則使用該查詢集的模型。

模型表單提供一個(gè)form_valid() 的實(shí)現(xiàn),它自動(dòng)保存模型。如果你有特殊的需求,可以覆蓋它;參見下面的例子。

你甚至不需要為CreateViewUpdateView提供success_url —— 如果存在它們將使用模型對(duì)象的get_absolute_url()。

如果你想使用一個(gè)自定義的ModelForm(例如添加額外的驗(yàn)證),只需簡(jiǎn)單地在你的視圖上設(shè)置form_class

當(dāng)指定一個(gè)自定義的表單類時(shí),你必須指定模型,即使form_class 可能是一個(gè)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 機(jī)器伙伴來做實(shí)際的工作。注意這里我們是如何配置通用的基于類的視圖的;我們自己沒有寫任何邏輯:

#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,因?yàn)樵谠撐募?dǎo)入時(shí)URL 還沒有加載。

fields 屬性的工作方式與ModelForm 的內(nèi)部Meta類的fields 屬性相同。除非你用另外一種方式定義表單類,該屬性是必須的,如果沒有將引發(fā)一個(gè)ImproperlyConfigured 異常。

如果你同時(shí)指定fieldsform_class 屬性,將引發(fā)一個(gè)ImproperlyConfigured 異常。

Changed in Django 1.8:

省略fields 屬性在以前是允許的,但是導(dǎo)致表單帶有模型的所有字段。
Changed in Django 1.8:

以前,如果fields 和form_class 兩個(gè)都指定,會(huì)默默地忽略 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并基于模型來構(gòu)造template_name。

在這個(gè)例子中:

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

如果你希望分開CreateViewUpdateView 的模板,你可以設(shè)置你的視圖類的template_nametemplate_name_suffix。

模型和request.user

為了跟蹤使用CreateView 創(chuàng)建一個(gè)對(duì)象的用戶,你可以使用一個(gè)自定義的ModelForm 來實(shí)現(xiàn)這點(diǎn)。首先,向模型添加外鍵關(guān)聯(lián):

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

    # ...

在這個(gè)視圖中,請(qǐng)確保你沒有將created_by 包含進(jìn)要編輯的字段列表,并覆蓋form_valid() 來添加這個(gè)用戶:

#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() 來裝飾這個(gè)視圖,或者在form_valid() 中處理未認(rèn)證的用戶。

AJAX 示例

下面是一個(gè)簡(jiǎn)單的實(shí)例,展示你可以如何實(shí)現(xiàn)一個(gè)表單,使它可以同時(shí)為AJAX 請(qǐng)求和‘普通的’表單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 文檔協(xié)作翻譯小組,原文:Built-in editing views。

本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請(qǐng)保留作者署名和文章出處。

Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。