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 ...
随机推荐
- mysql在关闭时的几个阶段
mysql关闭的大致过程 1.The shutdown process is initiated 初始化关机过程有许多种方法1.mysqladmin shutdown ; 2.kill pid_of_ ...
- php----浅谈一下empty isset is_null的用处
} } { } { } } } { } { } is_null():判断变量是否为null if ($a){} 那这个未声明变量会报noti ...
- ftp二进制与ascii传输方式区别
ASCII 和BINARY模式区别: 用HTML 和文本编写的文件必须用ASCII模式上传,用BINARY模式上传会破坏文件,导致文件执行出错. BINARY模式用来传送可执行文件,压缩文 ...
- 配置wamp环境使得在命令行下也能执行socket扩展
首先在apache中开启socket扩展 php环境安装目录\bin\apache\apache2.2.17\bin\php.ini 去掉前面的';' extension=php_sockets. ...
- Ext4.0.7使用Ext.grid.ColumnModel报错:TypeError: Ext.grid.Model is not a constructor
代码如下: Ext.onReady(function(){ //定义列 var cm = new Ext.grid.ColumnModel([ {header: '编号', dataIndex: 'i ...
- 省去在线安装 直接下载Chrome官方离线安装包
首页>软件之家>便捷上网 省去在线安装 直接下载Chrome官方离线安装包 2013-10-12 23:22:02来源:IT之家 原创作者:阿象责编:阿象人气:54487 评论:19 谷歌 ...
- 【转】【Android】HAL分析
原文网址:http://www.cnblogs.com/lcw/p/3335505.html HAL概述 以下是基于android4.0.3,对应其他低版本的代码,可能有所差异,但基本大同小异. An ...
- exe可执行程序及堆栈分配(转载)
可执行程序的内存分布 GNU编译器生成的目标文件默认格式为elf(executive linked file)格式,这是Linux系统所采用的可执行链接文件的通用文件格式.elf格式由若干个段(sec ...
- pyqt treeview基础学习
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' from PyQt4.QtGui import * from Py ...
- 平时的笔记02:处理fnmatch模块
# Copyright 2006 Joe Wreschnig## This program is free software; you can redistribute it and/or modif ...