python运维开发(十九)----Django后台表单验证、session、cookie、model操作
内容目录:
- Django后台表单验证
- CSRF加密传输
- session、cookie
- model数据库操作
Django后台Form表单验证
Django中Form一般有2种功能:
1、用于做用户提交数据的验证
- from django import forms
- class LoginForm(forms.Form):
基本验证demo
- from django.shortcuts import render,HttpResponse
- from django import forms
- import json
- # Create your views here.
- class LoginForm(forms.Form):
- user = forms.CharField(required=True)
- pwd = forms.CharField(required=True)
- def login(request):
- if request.method == 'POST':
- resault = {'status':False,'message':None}
- obj = LoginForm(request.POST)
- ret = obj.is_valid() #做Form的验证,如果填写正确返回为true否则返回false
- if ret:
- print(obj.clean())#正确时返回正确的值
- resault['status'] = True
- else:
- # print(type(obj.errors))#2通过Form方式来提交验证,错误时候打印错误信息类型,可以找到,
- # 通过错误类型导入ErrorDict模块,通过查看帮助信息,as_json方法,默认为as_ul方法
- from django.forms.utils import ErrorDict
- print(obj.errors.as_json())
- error_str = obj.errors.as_json()
- resault['message'] = json.loads(error_str)#这里由于上面的是一个字典格式需要先转换为字符串方式loads一下
- # return HttpResponse(error_str)#测试时候返回错误信息
- return HttpResponse(json.dumps(resault))
- # u = request.POST.get('user')#1正常情况ajax提交请求验证
- # p = request.POST.get('pwd')
- # print(u,p)
- return render(request,'login.html')
view--demo
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- .error_msg{
- color: red;
- }
- </style>
- </head>
- <body>
- <div>
- <div>
- <p>用户名:<input type="text" name="user"/></p>
- </div>
- <div>
- <p>密 码 :<input type="password" name="pwd"/></p>
- </div>
- <input type="button" value="提交" onclick="DoSubmit();" />
- </div>
- <script src="/static/jquery-1.8.2.min.js"></script>
- <script>
- function DoSubmit() {
- var input_dict = {};
- $('input').each(function () {
- var v = $(this).val();
- var n = $(this).attr('name');
- input_dict[n] = v;
- });
- console.log(input_dict);
- $('.error_msg').remove();
- $.ajax({
- url:'/login/',
- type:'POST',
- data:input_dict,
- dataType:'json',//默认返回过来的值为str字符串,可以通过转换为json,打印data为一个对象
- success:function (resault) {
- {# console.log(data);#}//打印data的值
- if (resault.status){
- location.href = '/index/'
- }else {
- $.each(resault.message,function (k,v) {//json方式转换为对象格式所以循环这个对象,因为这个对象为字典方式所以定义k和v
- {# console.log(k,v);#}
- console.log(k,v[0].message);//打印input的name和错误信息
- {# <span class="error_msg">错误信息</span>#}
- //将错误信息添加一个span标签到input后面
- var tag = document.createElement('span');
- tag.className = 'error_msg';
- tag.innerText = v[0].message;
- //input[name="user"]
- $('input[name="' +k +'"]').after(tag)
- })}
- }
- })
- }
- </script>
- </body>
- </html>
login.html
上面的提示中都是英文我们可以自定义自己的报错中文提示方式
只需要更改上面的views代码中LoginForm的类
- class LoginForm(forms.Form):
- user = forms.CharField(required=True,error_messages={'required':'用户名不能为空'})#中文提示
- pwd = forms.CharField(required=True,
- min_length=6,#最小长度为6
- #(默认提示Ensure this value has at least 6 characters (it has 3).)
- max_length=10,
- error_messages={'required': '密码不能为空',
- 'min_length':'最少6位',
- 'max_length':'最多10位'}
- )
上面的中我们使用的只是CharField字符类型,在实际的环境中我们可能会遇到数字的验证IntegerField
例如我们在上面的demo中添加一个num的文本框做数字的验证
- #required 默认为True,不填写该参数时候是treu
- num = forms.IntegerField(error_messages={'required': '数字不能为空',
- 'invalid':'输入的必须为数字',
- })
前端在密码后面添加上num的input文本框
- <div>
- <p>数 字 :<input type="text" name="num"/></p>
- </div>
效果展示
除了上面的两种类型外还有其他的我们常用的类型验证
CharField 字符类型验证
IntegerField 数字类型验证
URLField URL验证
EmailField 邮箱小地址验证
如果django不能满足我们需要的验证的话,我们还可以自定义的数字验证
- from django.core.exceptions import ValidationError
- 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):
- phone = forms.CharField(validators=[mobile_validate,],)
效果展示
2、用于做用户提交数据的验证 + 生成HTML标签
- from django.shortcuts import render,HttpResponse
- from django import forms
- import json,re
- from django.core.exceptions import ValidationError
- 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('手机号码格式错误')
- # Create your views here.
- class LoginForm(forms.Form):
- user = forms.CharField(required=True,error_messages={'required':'用户名不能为空'})#中文提示
- pwd = forms.CharField(required=True,
- min_length=6,#最小长度为6(默认提示Ensure this value has at least 6 characters (it has 3).)
- max_length=10,
- error_messages={'required': '密码不能为空',
- 'min_length':'最少6位',
- 'max_length':'最多10位'}
- )
- #required 默认为True,不填写该参数时候是treu
- num = forms.IntegerField(error_messages={'required': '数字不能为空',
- 'invalid':'输入的必须为数字',
- })
- phone = forms.CharField(validators=[mobile_validate,],)
- def login(request):
- if request.POST:
- objPost = LoginForm(request.POST)
- ret = objPost.is_valid() # 做Form的验证,如果填写正确返回为true否则返回false
- if ret:
- print(objPost.clean()) # 正确时返回正确的值
- else:
- from django.forms.utils import ErrorDict
- error_str = objPost.errors.as_json()
- # for k,v in objPost.errors.items():
- # print(k,v)
- # print(objPost.errors['user'][0])
- # print(objPost.errors['pwd'][0])
- # print(objPost.errors['num'][0])
- # print(objPost.errors['phone'][0])
- pass
- return render(request,'login.html',{'obj1':objPost})
- else:
- objGet = LoginForm()
- return render(request,'login.html',{'obj1':objGet})
views-demo
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- .error_msg{
- color: red;
- }
- </style>
- </head>
- <body>
- <form action="/login/" method="POST">
- <div>
- <div>
- <p>用户名:{{ obj1.user }}
- {% if obj1.errors.user %}
- <span class="error_msg">{{ obj1.errors.user.0 }}</span>
- {% endif %}
- </p>
- </div>
- <div>
- <p>密 码 :{{ obj1.pwd }}
- {% if obj1.errors.pwd %}
- <span class="error_msg">{{ obj1.errors.pwd.0 }}</span>
- {% endif %}
- </p>
- </div>
- <div>
- <p>数 字 :{{ obj1.num }}
- {% if obj1.errors.num %}
- <span class="error_msg">{{ obj1.errors.num.0 }}</span>
- {% endif %}
- </p>
- </div>
- <div>
- <p>手 机 :{{ obj1.phone }}
- {% if obj1.errors.phone %}
- <span class="error_msg">{{ obj1.errors.phone.0 }}</span>
- {% endif %}
- </p>
- </div>
- <input type="submit" value="提交" />
- </div>
- </form>
- </body>
- </html>
HTML-前端代码
通过后端来生成后端标签时候我们还可以定义自己的属性
- # test = forms.CharField(widget=forms.Textarea(attrs={'name': 'test'}))
- test_choices = (
- (0, '上海'),
- (1, '背景'),
- )
- test = forms.IntegerField(widget=forms.Select(choices=test_choices))
html代码
- <div>
- <p>测 试 :{{ obj1.test }}
- {% if obj1.errors.test %}
- <span class="error_msg">{{ obj1.errors.test.0 }}</span>
- {% endif %}
- </p>
- </div>
CSRF跨站请求伪造
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。
全局:
中间件 django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
注:from django.views.decorators.csrf import csrf_exempt,csrf_protect
1、普通表单提交应用
- #setting中配置
- MIDDLEWARE_CLASSES = [
- 'django.middleware.csrf.CsrfViewMiddleware',
- ]
- #urls配置
- url(r'^csrf/', views.csrf),
- #views配置
- def csrf(request):
- return render(request,'csrf.html')
- #前端添加导入csrf_token配置
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <form action="/csrf/" method="post">
- {% csrf_token %}
- <input type="text" name="v"/>
- <input type="submit" value="form提交" />
- </form>
- <input type="button" value="Ajax提交" onclick="DoAjax();" />
- </body>
- </html>
打开网页后调试模式我们能看到提交过来的一个字符串
2、Ajax提交应用
js脚本
- <script>
- var csrftoken = $.cookie('csrftoken');//从cookie获取值
- function csrfMethod(method) {
- return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
- }
- //所有ajax发送请求之前执行该ajaxSetup配置
- $.ajaxSetup({
- beforeSend:function (xhr,settings) {
- if (!csrfMethod(settings.type) && !this.crossDomain){
- xhr.setRequestHeader("X-CSRFToken",csrftoken);
- }
- }
- });
- function DoAjax() {
- $.ajax({
- url:'/csrf/',
- type:'POST',
- data:{'k1':'v1'},
- success:function (data) {
- console.log(data);
- }
- })
- }
- </script>
cookie、Session缓存
一、cookie
Cookie是保存在客户端浏览器上的一个容器
1、获取cookie
- request.COOKIES['key']
- request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
- 参数:
- default: 默认值
- salt: 加密盐
- max_age: 后台控制过期时间
2、设置cookie
- rep = HttpResponse(...) 或 rep = render(request, ...)
- rep.set_cookie(key,value,...)
- rep.set_signed_cookie(key,value,salt='加密盐',...)
- 参数:
- key, 键
- value='', 值
- max_age=None, 超时时间
- expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
- path='/', Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
- domain=None, Cookie生效的域名
- secure=False, https传输
- httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
由于cookie保存在客户端的电脑上,所以,JavaScript和jquery也可以操作cookie。
- <script src='/static/js/jquery.cookie.js'></script>
- $.cookie("list_pager_num", 30,{ path: '/' });
二、Session
一般Session依赖于cookie,Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:
- 数据库(默认)
- 缓存
- 文件
- 缓存+数据库
- 加密cookie
1、数据库Session
- Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
- a. 配置 settings.py
- SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
- SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
- SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
- SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
- SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认)
- SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认)
- SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认)
- SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
- SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)
- b. 使用
- def index(request):
- # 获取、设置、删除Session中数据
- request.session['k1']
- request.session.get('k1',None)
- request.session['k1'] = 123
- request.session.setdefault('k1',123) # 存在则不设置
- del request.session['k1']
- # 所有 键、值、键值对
- request.session.keys()
- request.session.values()
- request.session.items()
- request.session.iterkeys()
- request.session.itervalues()
- request.session.iteritems()
- # 用户session的随机字符串
- request.session.session_key
- # 将所有Session失效日期小于当前日期的数据删除
- request.session.clear_expired()
- # 检查 用户session的随机字符串 在数据库中是否
- request.session.exists("session_key")
- # 删除当前用户的所有Session数据
- request.session.delete("session_key")
数据库session
2、缓存Session
- a. 配置 settings.py
- SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
- SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
- SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
- SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径
- SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名
- SESSION_COOKIE_SECURE = False # 是否Https传输cookie
- SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输
- SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)
- SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期
- SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存
- b. 使用
- 同上
Session缓存
3、文件Session
- a. 配置 settings.py
- SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
- SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T
- SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
- SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径
- SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名
- SESSION_COOKIE_SECURE = False # 是否Https传输cookie
- SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输
- SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)
- SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期
- SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存
- b. 使用
- 同上
文件session
4、缓存+数据库Session
- 数据库用于做持久化,缓存用于提高效率
- a. 配置 settings.py
- SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
- b. 使用
- 同上
缓存+数据库
5、加密cookie Session
- a. 配置 settings.py
- SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
- b. 使用
- 同上
Session+cookie
models数据库操作
基本操作
进阶
双下划线
__ 大小于操作
__ 可以跨表
查询
1、一对多,查询所有用户类型等于 普通用户 的所有用户名和密码
2、三张表跨表操作
3、多对多
创建
操作_set
python运维开发(十九)----Django后台表单验证、session、cookie、model操作的更多相关文章
- python运维开发(十八)----Django(二)
内容目录 路由系统 模版 Ajax model数据库操作,ORM 路由系统 django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对 ...
- python运维开发(十六)----Dom&&jQuery
内容目录: Dom 查找 操作 事件 jQuery 查找 筛选 操作 事件 扩展 Dom 文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它 ...
- python运维开发(十四)----HTML基本操作
内容目录: HTML概述 head标签 body中常用标签 css选择器 css常用属性 HTML HTML概述 HTML是英文Hyper Text Mark-up Language(超文本标记语言) ...
- python运维开发(二十一)----文件上传和验证码+session
内容目录: 文件上传 验证码+session 文件和图片的上传功能 HTML Form表单提交,实例展示 views 代码 HTML ajax提交 原生ajax提交,XMLHttpRequest方式上 ...
- python运维开发(十五)----JavaScript
内容目录: HTML补充 javascript HTML补充 1.display标签 display的inline-block 属性会自动带3px的宽度 <span style="di ...
- python运维开发(十)----IO多路复用线程基本使用
内容目录: python作用域 python2.7和python3.5的多继承区别 IO多路复用 socketserver模块源分析 多线程.进程.协程 python作用域 python中无块级作用 ...
- python运维开发(十二)----rabbitMQ、pymysql、SQLAlchemy
内容目录: rabbitMQ python操作mysql,pymysql模块 Python ORM框架,SQLAchemy模块 Paramiko 其他with上下文切换 rabbitMQ Rabbit ...
- 运维开发笔记整理-django日志配置
运维开发笔记整理-django日志配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Django日志 Django使用python内建的logging模块打印日志,Pytho ...
- 来不及说什么了,Python 运维开发剁手价仅剩最后 2 天
51reboot 运维开发又双叒叕的搞活动了—— Python 运维开发 18 天训练营课程, 剁手价1299 最后2天 上课方式:网络直播/面授(仅限北京) DAY1 - DAY4 Python3 ...
随机推荐
- php中的MVC模式运用
[size=5][color=Red]php中的MVC模式运用[/color][/size] 首先我来举个例子: 一个简单的文章显示系统 简单期间,我们假定这个文章系统是只读的,也就是说这个例子将不涉 ...
- block(四)揭开神秘面纱(下)
看此篇时,请大家同时打开两个网址(或者下载它们到本地然后打开): http://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/BlocksRuntim ...
- 必须得是一万小时的 刻意训练(deliberate practice)
成功素质1:一万小时与格物致知 “格物致知14”的概念,我是从张银奎11老师那里了解到的.它的意思是“推究事物的原理,从而获得知识”,跟我在<透过现象看本质 - 写在观看WWDC 2016 Ke ...
- SSL和SSH和OpenSSH,OpenSSL有什么区别
ssl是通讯链路的附加层.可以包含很多协议.https, ftps, ..... ssh只是加密的shell,最初是用来替代telnet的.通过port forward,也可以让其他协议通过ssh的隧 ...
- 【转】 ubuntu下fastboot找不到devices
原文网址:http://memory.blog.51cto.com/6054201/1202420 转载补充: 1.首先,手机必须先进入bootloader状态,fastboot devices才能有 ...
- 《UNIX环境高级编程》笔记--chown,fchown和lchown函数
这三个函数都是用来更改文件的用户ID和组ID的,函数的定义如下: #include <unistd.h> int chown(const char *pathname, uid_t own ...
- mount命令汇总(转载)
(一)挂接命令(mount) 首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的. 命令格式: mount [-t vfstype] [-o op ...
- IO之流程与buffer概览
为了说明这个流程,还是用图来描述一下比较直观. 中间过程请参考 <IO之内核buffer----"buffer cache"> <IO之标准C库buffer> ...
- Hadoop 写SequenceFile文件 源代码
package com.tdxx.hadoop.sequencefile; import java.io.IOException; import org.apache.hadoop.conf.Conf ...
- OCP-1Z0-051-题目解析-第6题
6. Examine the structure of the SHIPMENTS table: name Null Type PO_ID ...