Django之Form組件
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):Form提交登錄驗證代碼login函數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})
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組件