表單(一)

單純從前端的html來說,表單是用來提交數據給服務器的,不管后臺的服務器用的是Django還是PHP語言還是其他語言。只要把input標簽放在form標簽中,然后再添加一個提交按鈕(submit),那么以后點擊提交按鈕,就可以將input標簽中對應的值提交給服務器了。

Django中的表單:
Django中的表單豐富了傳統的HTML語言中的表單。在Django中的表單,主要做以下兩件事:

<1> 渲染表單模板。
<2> 表單驗證數據是否合法

以生成'留言板'網頁為示例:

步驟<1> 新建'front app',新建'forms'

# forms

# 總覽一下,操作方法與'模型'類似
from django import forms

class MessageBoardForm(forms.Form): # 繼承Form類
    title=forms.CharField(max_length=10,min_length=2)
    content=forms.CharField(widget=forms.Textarea)# 使用widget(組件)指定'Textarea'類型
    email=forms.EmailField()
    reply=forms.BooleanField(required=False)# reply字段通過'required'參數取值,表示'可選','可不選'

步驟<2> '服務端'加載'MessageBoardForm'

# front.views

from django.shortcuts import render
from django.views.generic import View
from .forms import MessageBoardForm

# FormView用來處理'get'和'post'請求
class FormView(View):

    def get(self,request):
        # 生成空表單并傳遞context
        # 這個form對象包含了不少方法和屬性,可以了解
        form=MessageBoardForm()
        context={
            'form':form
        }
        return render(request,'index.html',context=context)
        

步驟<3> 前端模板的渲染并映射url

# index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Message Board</title>
</head>
<body>
    <form action="" method="post">
        <table>
            {{ form.as_table }} # 這里使用form對象的as_table渲染表單
            <tr>
                <td></td>
                <td>
                    <input type="submit" value="提交"> # 定義'提交'按鈕,發送數據
                </td>
            </tr>
        </table>
    </form>
</body>
</html>

'''
實際開發中,很少用到form.as_table,比如想插入CSS之類的樣式,這里要怎么破...
'''

# urls

from django.urls import path
from front import views

urlpatterns = [
    path('', views.FormView.as_view()),
]

啟動服務,刷新網頁,看看效果(每個'字段'會'自動'添加':'符號)
通過試驗,即使后端的'post'方法沒有定義,但是前端依然對'字段'作了限制
比如'content'字段不能為空,'email'字段的格式'隨便寫'也是不能通過的
(請不要'圖樣圖森破',以為'后端'就不用對'字段'作限制了...原因自己想...)

? 小小修改一下'forms.py',變更模板的標簽(通過'label'設置中文標簽)

# forms

from django import forms

class MessageBoardForm(forms.Form):
    # 通過label參數設置中文標簽
    title=forms.CharField(max_length=10,min_length=2,label='標題')
    content=forms.CharField(widget=forms.Textarea,label='內容')
    email=forms.EmailField(label='郵箱')
    reply=forms.BooleanField(required=False,label='回復')

步驟<4> 后端'post'方法編寫:

# views

from django.shortcuts import render
from django.views.generic import View
from .forms import MessageBoardForm
from django.http import HttpResponse

class FormView(View):

    def get(self,request):
        ......
        return render(request,'index.html',context=context)

    def post(self,request):
    
        # 這里依然涉及form對象的一些屬性和方法,有空可以去了解(is_valid和cleaned_data經常搭配使用)
        form=MessageBoardForm(request.POST) # 接收POST傳過來的'類字典對象'
        if form.is_valid(): # 驗證是否可用
            title=form.cleaned_data.get('title') # 利用cleaned_data屬性獲取對應的字段
            content=form.cleaned_data.get('content')
            email=form.cleaned_data.get('email')
            reply=form.cleaned_data.get('reply')
            # 終端獲取前端傳過來的數據
            print('*'*40)
            print(title)
            print(content)
            print(email)
            print(reply)
            print('*'*40)
            return HttpResponse('留言板回復成功!!!')
        else:
            print(form.errors) # 如果用戶發送的字段驗證失敗,'終端打印錯誤信息'
            return HttpResponse('fail!')
            '''
            <ul class="errorlist"><li>content<ul class="errorlist"><li>This field is required.</li></ul></li><li>title<ul class="errorlist"><li>This field is required.</li></ul></li><li>email<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
            '''
異常的處理:

errors屬性返回的'信息'并不友好,查看type(form.errors)
# class 'django.forms.utils.ErrorDict' ,errors實質就是'ErrorDict'的一個實例,查看源碼,我們調用get_json_data()返回更加友好的錯誤信息:

class FormView(View):

    ......
        else:
            # {'content': [{'message': 'This field is required.', 'code': 'required'}], 'title': [{'message': 'This field is required.', 'code': 'required'}], 'email': [{'message': 'This field is required.', 'code': 'required'}]}

            print(form.errors.get_json_data())
            return HttpResponse('fail!')
            '''
            顯然看起來更加清楚了
            '''

進一步的改進:使用中文'自定義'出錯內容

# forms

from django import forms

class MessageBoardForm(forms.Form):
    # 通過 error_messages 參數自定義'出錯信息'
    title=forms.CharField(max_length=10,min_length=2,label='標題',
                          error_messages=dict(min_length='字段不能少于2個字符'))
    content=forms.CharField(widget=forms.Textarea,label='內容',
                            error_messages=dict(required='必須輸入content字段'))
    email=forms.EmailField(label='郵箱',error_messages=dict(required='必須輸入email字段'))
    reply=forms.BooleanField(required=False,label='回復')
    
    '''
    {'content': [{'message': '必須輸入content字段', 'code': 'required'}], 'email': [{'message': '必須輸入email字段', 'code': 'required'}], 'title': [{'message': 'This field is required.', 'code': 'required'}]}
    '''

使用純前端的實例(例如前端不再使用form.as_table):

# forms

from django import forms

class MessageBoardForm(forms.Form):
   # 這里傳遞的key不僅僅只有'required',比如還有'invalid'
    email=forms.EmailField(label='郵箱',error_messages=dict(required='必須輸入email字段'))
    price=forms.FloatField(label='價格',error_messages=dict(invalid='請輸入正確的浮點類型'))
    
# views

from django.shortcuts import render
from django.views.generic import View
from .forms import MessageBoardForm
from django.http import HttpResponse
from django.forms.utils import ErrorDict

class FormView(View):
    
    # 不再傳遞context=form,直接加載前端表單
    def get(self,request):
        return render(request,'index.html')

    def post(self,request):
        form=MessageBoardForm(request.POST)
        if form.is_valid():# 字段的驗證,在調用is_valid()的時候,就會被驗證
            price=form.cleaned_data.get('price')
            return HttpResponse('數據提交成功!!!')
        else:
            print(form.errors.get_json_data()) # 最終都是調用get_json_data()方法
            return HttpResponse('數據提交失敗!')

# html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Message Board</title>
</head>
<body>
    <form action="" method="post">
        <label> 郵箱:
            <input type="text" name="email">
        </label>
        <label> 價格:
            <input type="text" name="price">
        </label>
        <input type="submit" value="submit">
    </form>
</body>
</html>

重啟服務,故意輸錯,看看終端的效果

'''
{'price': [{'message': '請輸入正確的浮點類型', 'code': 'invalid'}], 'email': [{'message': '必須輸入email字段', 'code': 'required'}]}
'''

注意:由于前端使用了純html語言,前端界面不會再對郵箱字段的'有效性'進行驗證,而我們之前使用form.as_table是可以從前端對字段的'有效性'進行驗證的!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容