Django基礎——Form&Ajax篇

一 Form

    在實際的生產環境中,登陸和註冊時用戶提交的數據瀏覽器端都會使用JavaScript來進行驗證(好比驗證輸入是否爲空以及輸入是否合法),可是瀏覽器可能會禁用JavaScirpt,同時也有人可能會搞注入攻擊,這樣瀏覽器端的驗證就沒法發揮做用(通常不會禁用),因此在實際項目中通常都會進行兩層驗證,即客戶端(瀏覽器)的驗證和服務器端的驗證。Django中的Form表單功能之一就是用來在服務器端對用戶提交的數據作驗證;它的另一個功能是生成HTML標籤。javascript

   假如沒有Django的Form表單,那麼咱們應該這麼作css

#/usr/bin/env python #-*- coding:utf-8 -*-

from django.shortcuts import render # Create your views here. # 獲取用戶的相關信息
def user_list(request): host = request.POST.get('host') port = request.POST.get('port') mail = request.POST.get('mail') mobile = request.POST.get('mobile') # 在這裏,存在兩個問題
    # 一、從用戶提交的數據中獲取具體字段的信息時,咱們要不停得get相關信息,若是字段不少,顯然過於繁瑣
    # 二、獲取的數據,咱們要本身進行合法性的驗證或特定格式的驗證,顯然也很麻煩

    return render(request,'user_list.html')

       Django中Form的做用:(1)生成HTML標籤;(2)用戶提交數據驗證html

  1 生成HTML標籤前端

   views.py文件java

#!/usr/bin/env python #-*- coding:utf-8 -*-

from django import forms,render # 用戶信息Form表單類,繼承自forms.Form
class UserInfo(forms.Form): email = forms.EmailField(required=True) #required=True,表示內容不能爲空
     host = forms.CharField() #默認requried=False,表示內容能夠爲空
     port = forms.CharField() mobile = forms.CharField() # 定義函數,參數爲request
def user_list(request): obj = UserInfo() #建立對象obj
    return render(request,'user_list.html',{'obj':obj})#把對象obj傳給html

  user_list.html文件python

<form action="/user_list/" method="post">
    <p>主機:{{ obj.host }}</p>
    <p>端口:{{ obj.port }}</p>
    <p>郵箱:{{ obj.email }}</p>
    <p>手機:{{ obj.mobile }}</p>
    <input type="submit" value="submit"/>
</form>

  2 簡單的Form表單驗證jquery

   views.py文件ajax

#!/usr/bin/env python #-*- coding:utf-8 -*-

from django import forms,render class UserInfo(forms.Form): email = forms.EmailField(required=False) #required是否能夠爲空,若是爲False說明能夠爲空
     host = forms.CharField() #若是required不寫,默認爲Ture
     port = forms.CharField() mobile = forms.CharField() def user_list(request): obj = UserInfo() #建立對象
    if request.method == 'POST': #獲取用戶輸入,用戶post的數據做爲參數傳遞給UserInfo這個自定義的表單類,生成相應的對象後就能夠作驗證了
        user_input_obj = UserInfo(request.POST) #判斷用戶輸入是否合法
        if user_input_obj.is_valid(): #獲取用戶輸入,這裏獲取的數據類型爲字典
            data = user_input_obj.clean() # 若是不合法
        else: #捕捉錯誤信息
            error_msg = user_input_obj.errors print type(error_msg) ''' <ul class="errorlist"> <li>mobile <ul class="errorlist"> <li>This field is required.</li> </ul> </li> <li>host <ul class="errorlist"> <li>This field is required.</li> </ul> </li> <li>port <ul class="errorlist"> <li>This field is required.</li> </ul> </li> </ul> '''
            #而後把錯誤信息返回
            return render(request,'user_list.html',{'obj':obj,'errors':error_msg,}) return render(request,'user_list.html',{'obj':obj,})

   user_list.html文件django

<form action="/user_list/" method="post">
    <p>主機:{{ obj.host }}<span>{{ errors.host }}</span></p>
    <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p>
    <p>郵箱:{{ obj.email }}<span>{{ errors.email }}</span></p>
    <p>手機:{{ obj.mobile }}<span>{{ errors.mobile }}</span></p>
    <input type="submit" value="submit"/>
</form>

 效果圖:json

  3 自定義Form表單驗證

  app01下forms模塊中的account.py文件

#!/usr/bin/env python #-*- coding:utf-8 -*-

from django import forms from django.core.exceptions import ValidationError import re #自定義手機號碼驗證方法
def mobile_validate(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') #正則匹配
    if not mobile_re.match(value): raise ValidationError('手機號碼格式錯誤') #若是沒有匹配到主動觸發一個錯誤

class LoginForm(forms.Form): user_type_choice = ( (1,'普通用戶'), (2,'超級用戶'), ) # 生成select標籤,而且添加相應的屬性
    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,attrs={'class':'r'})) # 參數required能夠省略,默認required=True,表示不能爲空
    username = forms.CharField(required=True,error_messages={'required':u'用戶名不能爲空'}) password = forms.CharField(required=True,error_messages={'required':u'密碼不能爲空'}) mobile = forms.CharField(validators=[mobile_validate,], #應用自定義的驗證方法
                             error_messages={'required':u'手機號碼不能爲空'},
# 生成提示信息,而且添加相應的屬性 widget
=forms.TextInput(attrs={'class':'r','placeholder':u'手機號碼'}) ) email = forms.EmailField(error_messages={'required':u'郵箱不能爲空'}, # 生成提示信息,而且添加相應的屬性,其中class=r是自定義的屬性 widget=forms.TextInput(attrs={'class':'r','placeholder':u'郵箱'}) ) # 新增一個 memo = forms.CharField(required=False, widget=forms.Textarea(attrs={'class':'r','placeholder':'備註'}) )

  app01下views模塊中的account.py文件

#!/usr/bin/env python #-*- coding:utf-8 -*-

from django.shortcuts import render,HttpResponse from app01.forms import account as AccountForm def login(request): obj = AccountForm.LoginForm() # 生成Form對象 if request.method == 'POST': user_input_obj = AccountForm.LoginForm(request.POST) # 把提交的數據封裝到Form對象中 # 判斷數據是否合法
        if user_input_obj.is_valid(): # 獲取提交的數據
            data = user_input_obj.clean() # 若是數據不合法
        else: error = user_input_obj.errors.as_data() # 注意下面變量的類型
            print type(error)   # <type 'dict'>

            print error['username'] # [ValidationError([u'\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a'])]
            print type(error['username']) # <type 'list'>

            print error['username'][0]  #[u'\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a']
            print type(error['username'][0]) #<class 'django.core.exceptions.ValidationError'>

            print error['username'][0][0] #用戶名不能爲空
            print type(error['username'][0][0]) #<type 'unicode'>

            return render(request,'account/login.html',{'obj':obj,'error':error}) return render(request,'account/login.html',{'obj':obj})
#默認是as_ul(),即顯示爲ul的樣式;若是寫成as_data(),返回的是一個原生的字符串;as_json()與as_data()同樣,
#也是返回的原生字符串 error_msg = user_input_obj.errors.as_data()

   app01下的templatetags模塊中的xx.py文件(由於模板語言不支持用索引的方式取值,因此咱們經過自定義simp_tag來進行取值)

#!/usr/bin/env python #-*- coding:utf-8 -*-

from django import template from django.utils.safestring import mark_safe from django.template.base import resolve_variable, Node, TemplateSyntaxError register = template.Library() @register.simple_tag def error_msg(arg): # 注意這裏要作判斷
    if arg: return arg[0][0] # 這裏的返回空字符串也是必須的,不然報錯
    return ''

   templates/account目錄下的login.html文件

{% load xx %} <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/common.css"/>
</head>
<body>
    <form action="/login/" method="post">
        <p> 用戶主機類型: {{ obj.user_type }} </p>

        <p> 姓名: {{ obj.username }} {#默認錯誤信息提示#} {#<span> {{ error.username }}</span>#} {#自定義錯誤信息提示#} <span> {% error_msg error.username %}</span>
        </p>
        <p> 密碼: {{ obj.password }} {#<span> {{ error.password }}</span>#} <span> {% error_msg error.password %}</span>
        </p>
        <p> 手機號碼: {{ obj.mobile }} {#<span> {{ error.mobile }}</span>#} <span> {% error_msg error.mobile %}</span>
        </p>
        <p> 郵箱: {{ obj.email }} {#<span> {{ error.email }}</span>#} <span> {% error_msg error.email %}</span>
        </p>
        <p> 備註: {{ obj.memo }} </p>

        <input type="submit" value="提交"/>

    </form>

</body>
</html>

 二 Ajax

    Django中怎麼把前端數據在不刷新前端頁面的前提下提交到後臺,這裏涉及到Django中Ajax提交數據到後臺的問題。主要包括:(1)利用Ajax把前端簡單數據(單條)提交到後臺;(2)利用Ajax把前端複雜數據(多條)提交到後臺。

 1 提交單條數據

   html頁面,注意其中的註釋

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ajax提交數據</title>
</head>
<body>
    <form action="/user_list/" method="post"> {# 提交數據button #} <input type="button" onclick="Ajaxsubmit();" value="Ajax提交"/>
        <table>
            <thead>
                <tr>
                    <th>主機名</th>
                    <th>端口</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>1.1.1.1</td>
                    <td>80000</td>
                </tr>
                <tr>
                    <td>1.1.1.1</td>
                    <td>80000</td>
                </tr>
            </tbody>
        </table>
    </form>
    <script type="text/javascript" src="/static/jquery-2.2.1.min.js"></script>
    <script type="text/javascript">
        function Ajaxsubmit(){ {# 這裏應該從表格中獲取數據,爲了省事這裏直接指定了數據 #} var host = '1.1.1.1'; var port = '8000';  $.ajax({  {# 提交到後臺的url #} url:"/ajax_data/", {# 提交到後臺的方式 #} type:'POST', {# 要提交的數據,簡單數據直接以字典的形式提交 #} data:{h:host,p:port}, {# 提交成功後要執行的函數,函數內容此處省略 #} success:function(arg){ } }) } </script>
</body>
</html>

    views.py文件

def ajax_data(request):
# 打印前端POST提交的數據
print request.POST return HttpResponse('ok')

    2 提交多條數據

   在上述的基礎上修改jQuery代碼

<script>
        function AjaxsubmitSet(){ var user_arr = [ {'username':'alex','age':18}, {'username':'eric','age':28}, {'username':'rain','age':38}, ]; {# Ajax提交 #} $.ajax({ url:"/ajax_data_set/", type:'POST', data:{data:user_arr}, success:function(arg){ } }) } </script>

    提交後打印的數據以下所示:

<QueryDict: {u'data[1][username]': [u'alex'], u'data[0][username]': [u'eric'], u'data[0][age]': [u'18'], 
u'data[1][age]': [u'28'], u'data[2][username]': [u'rain'], u'data[2][age]': [u'38']}>

    這明顯不符合格式要求,須要咱們進一步進行處理,繼續修改Ajax提交代碼以下:

<script>
        function AjaxsubmitSet(){ var user_arr = [ {'username':'alex','age':18}, {'username':'eric','age':28}, {'username':'rain','age':38}, ]; $.ajax({ {# Ajax提交url #} url:"/ajax_data_set/", {# Ajax提交方式 #} type:'POST', {# Ajax以原生的數據格式進行提交 #} tradition:true, {# Ajax提交只能處理字符粗,不能處理字典,這裏把字典轉換成字符串形式 #} data:{data:Json.stringify(user_arr)}, success:function(arg){ } }) } </script>

   3 進一步改進規範的寫法

   views.py文件的修改

import json # 後臺向前端返回數據 def ajax_data(request): # 設置初始的返回值
    ret = {'status':True,'error':''} # 捕捉錯誤
    try: print request.POST except Exception,e: #異常時,ret[status] = False
        ret['status'] = False # 注意這裏的str,這裏是把e封裝成字符串形式
        ret['error'] = str(e) # 因爲ret是字典形式,可是HttpResponse只能返回字符串,因此這裏把ret經過json.dumps()轉換成字符串形式
    return HttpResponse(json.dumps(ret))

   jQuery部分的修改

<script>
        function Ajaxsubmit(){ var user_arr = [ {'username':'alex','age':18}, {'username':'eric','age':28}, {'username':'rain','age':38}, ]; {# Ajax提交數據 #} $.ajax({ {# Ajax提交url #} url:"/ajax_data/", {# Ajax以POST方式提交 #} type:'POST', {# Ajax以原生形式提交數據 #} tradition: true,  {# Ajax只能提交字符串數據,這裏把字典轉換爲字符串 #} data:{data:JSON.stringify(user_arr)},  {# Ajax提交執行成功後的執行代碼,arg是後臺返回的數據,切記 #} success:function(arg){ //這裏把後臺返回的字符串arg轉換爲字典形式
                    var callback_dict = $.parseJSON(arg); //這裏只作簡單的判斷,判斷後臺返回的是否爲空
                    if(callback_dict){ //不爲空,則執行成功了
                        alert('提交成功') }else{ //不然,執行失敗了
 alert(callback_dict.error) } } }) } </script>

 

 

 

 

參考資料:

    http://www.cnblogs.com/wupeiqi/articles/5246483.html

    http://www.cnblogs.com/luotianshuai/p/5278175.html

相關文章
相關標籤/搜索