第二十二章html
内容:python
session、form验证、中间件、缓存、信号数据库
一.sessiondjango
Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:json
一、数据库Session浏览器
1 Django默认支持Session,而且默认是将Session数据存储在数据库中,即:django_session 表中。 2 3 a. 配置 settings.py 4 5 SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 6 7 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) 8 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) 9 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认) 10 SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认) 11 SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认) 12 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认) 13 SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过时(默认) 14 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改以后才保存(默认) 15 16 17 18 b. 使用 19 20 def index(request): 21 # 获取、设置、删除Session中数据 22 request.session['k1'] 23 request.session.get('k1',None) 24 request.session['k1'] = 123 25 request.session.setdefault('k1',123) # 存在则不设置 26 del request.session['k1'] 27 28 # 全部 键、值、键值对 29 request.session.keys() 30 request.session.values() 31 request.session.items() 32 request.session.iterkeys() 33 request.session.itervalues() 34 request.session.iteritems() 35 36 37 # 用户session的随机字符串 38 request.session.session_key 39 40 # 将全部Session失效日期小于当前日期的数据删除 41 request.session.clear_expired() 42 43 # 检查 用户session的随机字符串 在数据库中是否 44 request.session.exists("session_key") 45 46 # 删除当前用户的全部Session数据 47 request.session.delete("session_key") 48 49 request.session.set_expiry(value) 50 * 若是value是个整数,session会在些秒数后失效。 51 * 若是value是个datatime或timedelta,session就会在这个时间后失效。 52 * 若是value是0,用户关闭浏览器session就会失效。 53 * 若是value是None,session会依赖全局session失效策略。
二、缓存Session缓存
1 a. 配置 settings.py 2 3 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 4 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也能够是memcache),此处别名依赖缓存的设置 5 6 7 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串 8 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径 9 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 10 SESSION_COOKIE_SECURE = False # 是否Https传输cookie 11 SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输 12 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) 13 SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过时 14 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改以后才保存 15 16 17 18 b. 使用 19 20 同上
三、文件Session服务器
1 a. 配置 settings.py 2 3 SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 4 SESSION_FILE_PATH = None # 缓存文件路径,若是为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T 5 6 7 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串 8 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径 9 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 10 SESSION_COOKIE_SECURE = False # 是否Https传输cookie 11 SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输 12 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) 13 SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过时 14 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改以后才保存 15 16 b. 使用 17 18 同上
四、缓存+数据库Sessioncookie
1 数据库用于作持久化,缓存用于提升效率 2 3 a. 配置 settings.py 4 5 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 6 7 b. 使用 8 9 同上
五、加密cookie Sessionsession
1 a. 配置 settings.py 2 3 SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 4 5 b. 使用 6 7 同上
扩展:Session用户验证
1 def login(func): 2 def wrap(request, *args, **kwargs): 3 # 若是未登录,跳转到指定页面 4 if request.path == '/test/': 5 return redirect('http://www.baidu.com') 6 return func(request, *args, **kwargs) 7 return wrap
2、form
django中的Form通常有两种功能:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import re 4 from django import forms 5 from django.core.exceptions import ValidationError 6 7 8 def mobile_validate(value): 9 mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') 10 if not mobile_re.match(value): 11 raise ValidationError('手机号码格式错误') 12 13 14 class PublishForm(forms.Form): 15 16 user_type_choice = ( 17 (0, u'普通用户'), 18 (1, u'高级用户'), 19 ) 20 21 user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice, 22 attrs={'class': "form-control"})) 23 24 title = forms.CharField(max_length=20, 25 min_length=5, 26 error_messages={'required': u'标题不能为空', 27 'min_length': u'标题最少为5个字符', 28 'max_length': u'标题最多为20个字符'}, 29 widget=forms.TextInput(attrs={'class': "form-control", 30 'placeholder': u'标题5-20个字符'})) 31 32 memo = forms.CharField(required=False, 33 max_length=256, 34 widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'详细描述', 'rows': 3})) 35 36 phone = forms.CharField(validators=[mobile_validate, ], 37 error_messages={'required': u'手机不能为空'}, 38 widget=forms.TextInput(attrs={'class': "form-control", 39 'placeholder': u'手机号码'})) 40 41 email = forms.EmailField(required=False, 42 error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'}, 43 widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'})) 44 45 Form
1 def publish(request): 2 ret = {'status': False, 'data': '', 'error': '', 'summary': ''} 3 if request.method == 'POST': 4 request_form = PublishForm(request.POST) 5 if request_form.is_valid(): 6 request_dict = request_form.clean() 7 print request_dict 8 ret['status'] = True 9 else: 10 error_msg = request_form.errors.as_json() 11 ret['error'] = json.loads(error_msg) 12 return HttpResponse(json.dumps(ret)) 13 14 View
扩展:ModelForm
在使用Model和Form时,都须要对字段进行定义并指定类型,经过ModelForm则能够省去From中字段的定义
1 class AdminModelForm(forms.ModelForm): 2 3 class Meta: 4 model = models.Admin 5 #fields = '__all__' 6 fields = ('username', 'email') 7 8 widgets = { 9 'email' : forms.PasswordInput(attrs={'class':"alex"}), 10 }
3、缓存
因为Django是动态网站,全部每次请求均会去数据进行相应的操做,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将 一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则再也不去执行view中的操做,而是直接从内存或者Redis中 以前缓存的内容拿到,并返回。
Django中提供了6种缓存方式:
一、配置
a、开发调试
1 # 此为开始调试用,实际内部不作任何操做 2 # 配置: 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎 6 'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过时,0表示当即过时) 7 'OPTIONS':{ 8 'MAX_ENTRIES': 300, # 最大缓存个数(默认300) 9 'CULL_FREQUENCY': 3, # 缓存到达最大个数以后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) 10 }, 11 'KEY_PREFIX': '', # 缓存key的前缀(默认空) 12 'VERSION': 1, # 缓存key的版本(默认1) 13 'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】) 14 } 15 } 16 17 18 # 自定义key 19 def default_key_func(key, key_prefix, version): 20 """ 21 Default function to generate keys. 22 23 Constructs the key used by all other methods. By default it prepends 24 the `key_prefix'. KEY_FUNCTION can be used to specify an alternate 25 function with custom key making behavior. 26 """ 27 return '%s:%s:%s' % (key_prefix, version, key) 28 29 def get_key_func(key_func): 30 """ 31 Function to decide which key function to use. 32 33 Defaults to ``default_key_func``. 34 """ 35 if key_func is not None: 36 if callable(key_func): 37 return key_func 38 else: 39 return import_string(key_func) 40 return default_key_func
b、内存
1 # 此缓存将内容保存至内存的变量中 2 # 配置: 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 6 'LOCATION': 'unique-snowflake', 7 } 8 } 9 10 # 注:其余配置同开发调试版本
c、文件
1 # 此缓存将内容保存至文件 2 # 配置: 3 4 CACHES = { 5 'default': { 6 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 7 'LOCATION': '/var/tmp/django_cache', 8 } 9 } 10 # 注:其余配置同开发调试版本
d、数据库
1 # 此缓存将内容保存至数据库 2 3 # 配置: 4 CACHES = { 5 'default': { 6 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 7 'LOCATION': 'my_cache_table', # 数据库表 8 } 9 } 10 11 # 注:执行建立表命令 python manage.py createcachetable
e、Memcache缓存(python-memcached模块)
1 # 此缓存使用python-memcached模块链接memcache 2 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 6 'LOCATION': '127.0.0.1:11211', 7 } 8 } 9 10 CACHES = { 11 'default': { 12 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 13 'LOCATION': 'unix:/tmp/memcached.sock', 14 } 15 } 16 17 CACHES = { 18 'default': { 19 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 20 'LOCATION': [ 21 '172.19.26.240:11211', 22 '172.19.26.242:11211', 23 ] 24 } 25 }
f、Memcache缓存(pylibmc模块)
1 # 此缓存使用pylibmc模块链接memcache 2 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 6 'LOCATION': '127.0.0.1:11211', 7 } 8 } 9 10 CACHES = { 11 'default': { 12 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 13 'LOCATION': '/tmp/memcached.sock', 14 } 15 } 16 17 CACHES = { 18 'default': { 19 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 20 'LOCATION': [ 21 '172.19.26.240:11211', 22 '172.19.26.242:11211', 23 ] 24 } 25 }
二、应用
a. 全站使用
1 使用中间件,通过一系列的认证等操做,若是内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户以前,判断缓存中是否已经存在,若是不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存 2 3 MIDDLEWARE = [ 4 'django.middleware.cache.UpdateCacheMiddleware', 5 # 其余中间件... 6 'django.middleware.cache.FetchFromCacheMiddleware', 7 ] 8 9 CACHE_MIDDLEWARE_ALIAS = "" 10 CACHE_MIDDLEWARE_SECONDS = "" 11 CACHE_MIDDLEWARE_KEY_PREFIX = ""
b. 单独视图缓存
方式一: from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): ... 方式二: from django.views.decorators.cache import cache_page urlpatterns = [ url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)), ]
c、局部视图使用
1 a. 引入TemplateTag 2 3 {% load cache %} 4 5 b. 使用缓存 6 7 {% cache 5000 缓存key %} 8 缓存内容 9 {% endcache %}
4、信号
Django中提供了“信号调度”,用于在框架执行操做时解耦。通俗来说,就是一些动做发生的时候,信号容许特定的发送者去提醒一些接受者。
一、Django内置信号
1 Model signals 2 pre_init # django的modal执行其构造方法前,自动触发 3 post_init # django的modal执行其构造方法后,自动触发 4 pre_save # django的modal对象保存前,自动触发 5 post_save # django的modal对象保存后,自动触发 6 pre_delete # django的modal对象删除前,自动触发 7 post_delete # django的modal对象删除后,自动触发 8 m2m_changed # django的modal中使用m2m字段操做第三张表(add,remove,clear)先后,自动触发 9 class_prepared # 程序启动时,检测已注册的app中modal类,对于每个类,自动触发 10 Management signals 11 pre_migrate # 执行migrate命令前,自动触发 12 post_migrate # 执行migrate命令后,自动触发 13 Request/response signals 14 request_started # 请求到来前,自动触发 15 request_finished # 请求结束后,自动触发 16 got_request_exception # 请求异常后,自动触发 17 Test signals 18 setting_changed # 使用test测试修改配置文件时,自动触发 19 template_rendered # 使用test测试渲染模板时,自动触发 20 Database Wrappers 21 connection_created # 建立数据库链接时,自动触发
对于Django内置的信号,仅需注册指定信号,当程序执行相应操做时,自动触发注册函数:
1 from django.core.signals import request_finished 2 from django.core.signals import request_started 3 from django.core.signals import got_request_exception 4 5 from django.db.models.signals import class_prepared 6 from django.db.models.signals import pre_init, post_init 7 from django.db.models.signals import pre_save, post_save 8 from django.db.models.signals import pre_delete, post_delete 9 from django.db.models.signals import m2m_changed 10 from django.db.models.signals import pre_migrate, post_migrate 11 12 from django.test.signals import setting_changed 13 from django.test.signals import template_rendered 14 15 from django.db.backends.signals import connection_created 16 17 18 def callback(sender, **kwargs): 19 print("xxoo_callback") 20 print(sender,kwargs) 21 22 xxoo.connect(callback) 23 # xxoo指上述导入的内容
1 from django.core.signals import request_finished 2 from django.dispatch import receiver 3 4 @receiver(request_finished) 5 def my_callback(sender, **kwargs): 6 print("Request finished!")
二、自定义信号
a. 定义信号
1 import django.dispatch 2 pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
b. 注册信号
1 def callback(sender, **kwargs): 2 print("callback") 3 print(sender,kwargs) 4 5 pizza_done.connect(callback)
c. 触发信号
from 路径 import pizza_done pizza_done.send(sender='seven',toppings=123, size=456)
因为内置信号的触发者已经集成到Django中,因此其会自动调用,而对于自定义信号则须要开发者在任意位置触发
上课笔记:
day22知识点概要 - Session - CSRF - Model操做 - Form验证(ModelForm) - 中间件 - 缓存 - 信号内容详细:1. Session 基于Cookie作用户验证时:敏感信息不适合放在cookie中 a. Session原理 Cookie是保存在用户浏览器端的键值对 Session是保存在服务器端的键值对 b. Cookie和Session对比 c. Session配置(缺乏cache) d. 示例:实现两周自动登录 - request.session.set_expiry(60*10) - SESSION_SAVE_EVERY_REQUEST = True PS: cookie中不设置超时时间,则表示关闭浏览器自动清除 - session依赖于cookie - 服务器session request.session.get() request.session[x] = x request.session.clear() - 配置文件中设置默认操做(通用配置): 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过时(默认) # set_cookie('k',123) SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改以后才保存(默认) - 引擎的配置 2. CSRF a. CSRF原理 b. 无CSRF时存在隐患 c. Form提交(CSRF) d. Ajax提交(CSRF) CSRF请求头 X-CSRFToken 6. 中间件7. 缓存 5种配置 3种应用: 全局 视图函数 模板8. 信号 - 内置信号 - 自定义 - 定义信号 - 出发信号 - 信号中注册函数 3. Model操做 a. 字段类型 + 参数 b. 连表字段 + 参数 c. Meta d. SQL操做: - 基本增删改查 - 进阶操做 - 正反查询 - 其余操做 e. 验证(弱)4. Form操做 完成: - 验证用户请求 - 生成HTML (保留上一次提交的数据) 自定义: - 类 - 字段(校验) - 插件(生成HTML) 初始化操做: a. Form验证用户请求 b. Form生成HTML c. Form字段详细(自定义字段,Model...) + 插件 d. 自定义验证(钩子以及__all__) e. 注册示例: 用户名、密码、邮箱、手机号(RegexValidator或RegexField)、性别、爱好、城市 f. 初始化值5. ModelForm a. Model+Form功能集合 b. save c. save + save_m2m