1. 程式人生 > >Django之Form組件

Django之Form組件

組件 return 生命 檢驗 ati mps 作用 網站 label

1.內容回顧

1)Django請求生命周期

HTTP請求->WSGI服務器(WEB服務網關接口)->中間件->url(路由系統)->view(匹配視圖函數)->views從model取數據->從前端拿模板->模板渲染給用戶返回一個大的字符串(網頁內容)    

2)Session是什麽?

Session:是保存在服務端的數據,當用戶登錄時,服務端生成隨機字符串給客戶端的瀏覽器,瀏覽器寫到cookie裏,服務器端把隨機字符串保存起來,服務端的隨機字符串和客戶端的cookie裏的隨機字符串一一對應。

3)XSS是什麽?

XSS:跨站腳本攻擊
        舉例:評論(while循環,alert),
        防止XSS(
1.客戶端提交什麽數據,以安全的形式查看,當作字符串讓用戶訪問,2.用戶提交時過濾關鍵字,如script)

4)CSRF-POST(銀行的例子) 兩個網站

CSRF:跨站請求偽造(POST請求)
        不僅發送數據,還要發送隨機字符串(上一次POST請求獲取到的)

2.今日內容:

Form組件

Form作用有兩個1.用戶提交數據進行校驗;2.保留上次輸入內容

提交數據方式:1.Form提交;2.Ajax提交

1. 用戶提交數據進行校驗

- Form提交(刷新,失去上次內容)
a. LoginForm(Form)
字段名 = xxxx.xxField() # 本質就是驗證規則,正則表達式
字段名 
= xxxx.xxField() # 本質驗證規則,正則表達式 字段名 = xxxx.xxField() # 本質驗證規則,正則表達式 字段名 = xxxx.xxField() # 本質驗證規則,正則表達式 b. obj = LoginForm(用戶提交的數據,request.POST) c. result = obj.is_valid() 進行校驗 print(result)返回True 或者False d. obj.cleaned_data:是一個字典,如果校驗成功了,拿到正確的值 e. obj.errors:是一個對象,包含所有的錯誤信息

內部原理

技術分享
def login(request):
    
if request.method == GET: return render(request, login.html) else: obj = LoginForm(request.POST) #is_valid """ 獲取當前類所有的對象 1.LoginForm實例化時,self.fields中 self.fields={ user:正則表達式, pwd:正則表達式, } 2.循環self.fields, flag = True驗證通過(用戶名密碼。。都輸入正確) errors cleaned_data for k,v in self.fields.items(): k是user,pwd v是:正則表達式 input_value = request.POST.get(k):前端輸入的值,寫幾個字段,就取誰 正則表達式和input_value進行正則匹配(這裏用的是match) flag = False return flag """ if obj.is_valid():#如果正確 print(obj.cleaned_data)#字典類型 return redirect(http://www.baidu.com) else: print(obj.errors) return render(request, login.html, {obj:obj})
Form提交登錄驗證代碼login函數 技術分享
def login(request):
                        if request.method == GET:
                            return render(request,login.html)
                        else:
                            obj = LoginForm(request.POST)
                            # is_valid
                            """
                            1. LoginForm實例化時,
                                self.fields={
                                    user: 正則表達式
                                    pwd: 正則表達式
                                }
                            2. 循環self.fields
                                  flag = True
                                  errors
                                  cleaned_data
                                  for k,v in self.fields.items():
                                    # 1. user,正則表達式
                                    input_value = request.POST.get(k)
                                    正則表達式和input_value
                                    flag = False
                                  return flag
                           """
                            if obj.is_valid():
                                print(obj.cleaned_data)
                            else:
                                print(obj.errors)
                            return render(request,login.html)
View Code 技術分享
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <h1>用戶登錄</h1>
    <form id="f1" action="/login/" method="POST">
        {% csrf_token %}
        <p>
            用戶名:<input type="text" name="user" />{{ obj.errors.user.0 }}
        </p>
        <p>
            密碼:<input type="password" name="pwd" />{{ obj.errors.pwd.0 }}
        </p>
        <input type="submit" value="提交">
        <a onclick="submitForm();">提交</a>    #onclick綁定事件
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        function submitForm(){
            $(.c1).remove();    #把以前的錯誤信息都清除掉
            $.ajax({
                url:/ajax_login/,    
                type:POST,        #提交方式
                data:$(#f1).serialize(),    #找到f1標簽,jQuery ajax - serialize() 方法,serialize() 方法通過序列化表單值,創建 URL 編碼文本字符串。
                datatype:"JSON",                    #serialize()拼接字符串,  user=alex&pwd=456&csrf_token=bing
                success:function(arg){
                    console.log(arg);
                    if (arg.status){

                    }else{
                        $.each(arg.msg,function (index,value) {    循環把所有錯誤信息輸出index,value(也就是key和value )
                            console.log(index,value);
                            var tag = document.createElement(span);    #創建節點:
                            tag.innerHTML = value[0];        #獲取第一個錯誤信息,innerHTML 給節點添加html代碼:
                            tag.className = c1;
                            $(#f1).find(input[name="+ index +"]).after(tag);    #在span標簽的後面
                            //‘  input[name="  ‘ + index + ‘  "]  ‘==input[name=user]
                        })
                    }
                }
            })
        }
    </script>

</body>
</html>
前端login.html代碼

前端涉及知識點:

1) createElement(標簽名) :創建一個指定名稱的元素。

例:var tag=document.createElement(“input")
tag.setAttribute(‘type‘,‘text‘);

2)data:$(‘#f1‘).serialize() serialize() 方法可以操作已選取個別表單元素的 jQuery 對象,比如 <input>, <textarea> 以及 <select>。

不過,選擇 <form> 標簽本身進行序列化一般更容易些:
打包user,pwd,csrf_token,拼接字符串

咱們寫的字典也會變成字符串
請求體:‘user=alex&pwd=456&csrf_token=bing‘

註意:render的本質還是返回HttpResponse(字符串)

return render():
def render(request, template_name, context=None, content_type=None, status=None, using=None):
"""
Returns a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)

2.- Ajax提交(不刷新,上次內容自動保留)

PS: Ajax提交(頁面不刷新,數據不清空) > Form提交(Form表單一刷新,頁面刷新,輸入的數據都會清空) 總結:

class Foo(Form):
            字段 = 正則表達式  :是否可以為空,最長,最短
            字段 = 自定義正則表達式
                   1. 常用
                        charField 
  ... 定義正則表達式 參數: 驗證:(本質上都是正則表達式) required error_messages 生成HTML標簽: widget
=widgets.Select, ******** 用於指定生成怎樣的HTML,select,text,input/. label=用戶名, # obj.t1.label disabled=False, # 是否可以編輯 label_suffix=--->, # Label內容後綴 initial=666, # 無用,猜測有問題應該在input框中顯示默認值 help_text=。。。。。。, # 提供幫助信息

- 生成HTML標簽
- 保留上次輸入內容

IntegerField繼承Field
CharField 繼承Field
EmailField繼承 CharField
URLField繼承CharField

t4 = fields.URLField()
t5 = fields.SlugField() #字母數字下劃線,內部也是正則表達式
t6 = fields.GenericIPAddressField()
t7 = fields.DateTimeField()
t8 = fields.DateField()
技術分享
def ajax_login(request):
    # request.POST.get()
    import json
    ret = {status:True,msg:None}
    obj = LoginForm(request.POST)
    if obj.is_valid():
        print(obj.cleaned_data)#{user: alex, pwd: alexalexalexalexalex}
    else:
        print(obj.errors)#obj.errors,是一個 對象(無序列表)
        ret[status] = True
        ret[msg] = obj.errors
        # error = json.dumps(obj.errors)
        # print(error)
    v = json.dumps(ret)
    print(v)#輸入錯誤:輸出{"status": true, "msg": {"user": ["This field is required."], "pwd": ["This field is required."]}}
    #輸入正確:{"status": true, "msg": null}
    return HttpResponse(v)#提交錯誤時,<ul class="errorlist"><li>user<ul class="errorlist"><li>This field is required.</li></ul></li><li>pwd<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
#ajax提交
# {user: alex, pwd: alexalexalexalexalex}
    # return render()
AJAX提交方式(ajax_login函數) 技術分享
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        function submitForm(){
            $(.c1).remove();
            $.ajax({
                url:/ajax_login/,
                type:POST,
                data:$(#f1).serialize(),
                datatype:"JSON",
                success:function(arg){
                    console.log(arg);
                    if (arg.status){

                    }else{
                        $.each(arg.msg,function (index,value) {
                            console.log(index,value);
                            var tag = document.createElement(span);
                            tag.innerHTML = value[0];
                            tag.className = c1;
                            $(#f1).find(input[name="+ index +"]).after(tag);
                        })
                    }
                }
            })
        }
    </script>
前端jQuery+AJAX代碼

Form組件之常用字段和參數

技術分享
Field
    required=True,               是否允許為空
    widget=None,                 HTML插件
    label=None,                  用於生成Label標簽或顯示內容
    initial=None,                初始值
    help_text=‘‘,                幫助信息(在標簽旁邊顯示)
    error_messages=None,         錯誤信息 {required: 不能為空, invalid: 格式錯誤}
    show_hidden_initial=False,   是否在當前插件後面再加一個隱藏的且具有默認值的插件(可用於檢驗兩次輸入是否一直)
    validators=[],               自定義驗證規則
    localize=False,              是否支持本地化
    disabled=False,              是否可以編輯
    label_suffix=None            Label內容後綴
Field

Django之Form組件