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请求获取到的)
Form作用有两个1.用户提交数据进行校验;2.保留上次输入内容
提交数据方式:1.Form提交;2.Ajax提交
- 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})
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‘)
<!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>
前端涉及知识点:
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)
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()
<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>
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内容后缀
原文:http://www.cnblogs.com/bingabcd/p/7119207.html