您的位置:首页 > 编程语言 > Go语言

django form表单插件,中间件,缓存,信号

2017-09-18 14:16 796 查看
一、form插件
django form表单类的字段和插件,字段用于表单验证获取数据,插件用来生成html代码
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内容后缀

CharField(Field)
max_length=None,             最大长度
min_length=None,             最小长度
strip=True                   是否移除用户输入空白

IntegerField(Field)
max_value=None,              最大值
min_value=None,              最小值

DecimalField(IntegerField)
max_value=None,              最大值
min_value=None,              最小值
max_digits=None,             总长度
decimal_places=None,         小数位长度

RegexField(CharField)
regex,                      自定制正则表达式
max_length=None,            最大长度
min_length=None,            最小长度
error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}

EmailField(CharField)
FileField(Field)
allow_empty_file=False     是否允许空文件

ChoiceField(Field)
...
choices=[],                选项,如:choices = [(0,'上海'),(1,'北京'),]
required=True,             是否必填
widget=None,               插件,默认select插件
label=None,                Label内容
initial=None,              初始值
help_text='',              帮助提示

FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
path,                      文件夹路径
match=None,                正则匹配
recursive=False,           递归下面的文件夹
allow_files=True,          允许文件
allow_folders=False,       允许文件夹
required=True,
widget=None,
label=None,
initial=None,
help_text=''

GenericIPAddressField
protocol='both',           both,ipv4,ipv6支持的IP格式
unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用
二、form验证规则
新建模块forms.py
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from app01 import models
import re
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator

class UserInfoForm(Form):
name = fields.CharField(
required=True,
min_length=6,
max_length=12
)
email = fields.EmailField(
required=True,
)
方法一: RegexValidator对象
phone = fields.CharField(
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')]
)

方式二:函数
def mobile_validate(value):
mobile_re = re.compile(r'^(13[0-9]|15[0123456789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(value):
raise ValidationError('手机号码格式错误')

phone = fields.CharField(
validators= [mobile_validate,]
)

方法三:当前类的方法中,方法名称要求: clean_phone方法
phone = fields.CharField()

def clean_phone(self):
# 去取用户提交的值:可能是错误的,可能是正确
value = self.cleaned_data['phone']
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('手机号码格式错误')

if models.UserInfo.objects.filter(phone=value).count():
raise ValidationError('手机号码已经存在')

return value

注册确认密码认证clean函数
class RegisterForm(Form):
name = fields.CharField(
widget=widgets.TextInput(attrs={'class': 'c1'})
)

email = fields.EmailField(
widget=widgets.EmailInput(attrs={'class': 'c1'})
)

phone = fields.CharField(
widget=widgets.Textarea(attrs={'class': 'c1'})
)

pwd = fields.CharField(
widget=widgets.PasswordInput(attrs={'class': 'c1'})
)

pwd_confirm = fields.CharField(
widget=widgets.PasswordInput(attrs={'class': 'c1'})
)

dp_id = fields.ChoiceField(
choices=[]
)

roles_id = fields.ChoiceField(
choices=[]
)

def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
self.fields['dp_id'].choices = models.Depart.objects.values_list('id', 'title')
self.fields['roles_id'].choices = models.Role.objects.values_list('id', 'name')

def clean(self):
pwd = self.cleaned_data['pwd']
pwd_confirm = self.cleaned_data['pwd_confirm']
if pwd == pwd_confirm:
return self.cleaned_data
else:
from django.core.exceptions import ValidationError
self.add_error('pwd_confirm', ValidationError('密码输入不一致'))
return self.cleaned_data
三、中间件
项目目录下新建目录md
md目录新建middleware.py文件
from django.shortcuts import HttpResponse,redirect

class MiddlewareMixin:
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin,self).__init__()

def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response

class M1(MiddlewareMixin):
def process_request(self, request):
print('m1.process_request')

def process_view(self, request, callback, callback_args, callback_kwargs):
print('m1.process_view', callback)

def process_exception(self,request,exception):
print('m1.process_exception')

def process_response(self,request,response):
print('m1.process_response')
return response

class M2(MiddlewareMixin):
def process_request(self, request):
print('m2.process_request')

def process_view(self,request,callback, callback_args, callback_kwargs):
print('m2.process_view', callback)

def  process_response(self,request, response):
print('m2.process_response')
return response

def process_exception(self,request,exception):
print('m2.process_exception')

settings.py文件中间件添加
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'md.middleware.M1',    #添加项
'md.middleware.M2',    #添加项
]

中间件是一个类
中间件中一共有四个方法:
process_request
process_view
process_exception
process_response

已经添加中间件M1和M2
中间件执行时机: 请求到来,请求返回时
- 应用:
- 请求日志
- 用户登录认证



四、缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会
更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,
5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿
到,并返回

Django中提供了6种缓存方式:
1. 开发调试
2. 内存
3. 文件
4. 数据库
5. Memcache缓存(python-memcached模块)
6. Memcache缓存(pylibmc模块)

a.开发调试
# 此为开始调试用,实际内部不做任何操作
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',     # 引擎
'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3,    # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
},
'KEY_PREFIX': '', # 缓存key的前缀(默认空)
'VERSION': 1,     # 缓存key的版本(默认1)
'KEY_FUNCTION' 函数名    # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
}
}

def default_key_func(key, key_prefix, version):
return '%s:%s:%s' % (key_prefix, version, key)

def get_key_func(key_func):
if key_func is not None:
if callable(key_func):
return key_func
else:
return import_string(key_func)
return default_key_func

b. 内存缓存
此缓存将内容保存至内存的变量中
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}

c. 文件缓存
# 此缓存将内容保存至文件
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}

d. 数据库缓存
# 此缓存将内容保存至数据库

# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # 数据库表
}
}

e. Memcache缓存(python-memcached模块)
# 此缓存使用python-memcached模块连接memcache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'unix:/tmp/memcached.sock',
}
}

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}

f. Memcache缓存(pylibmc模块)
# 此缓存使用pylibmc模块连接memcache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '127.0.0.1:11211',
}
}

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '/tmp/memcached.sock',
}
}

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}

缓存使用方法
1. 全站应用配置
使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获
取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则
UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存

MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',        # 其他中间件...
'django.middleware.cache.FetchFromCacheMiddleware',
]

#CACHE_MIDDLEWARE_ALIAS = ""
# CACHE_MIDDLEWARE_SECONDS = ""
# CACHE_MIDDLEWARE_KEY_PREFIX = ""

2.单独视图函数
方式一:
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)),
]

3.局部视图使用
a. 引入TemplateTag

{% load cache %}

b. 使用缓存

{% cache 5000 缓存key %}
缓存内容
{% endcache %}

五、信号
1.内置信号
Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,
信号允许特定的发送者去提醒一些接受者

Model signals
pre_init                    # django的modal执行其构造方法前,自动触发
post_init                   # django的modal执行其构造方法后,自动触发
pre_save                    # django的modal对象保存前,自动触发
post_save                   # django的modal对象保存后,自动触发
pre_delete                  # django的modal对象删除前,自动触发
post_delete                 # django的modal对象删除后,自动触发
m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
pre_migrate                 # 执行migrate命令前,自动触发
post_migrate                # 执行migrate命令后,自动触发
Request/response signals
request_started             # 请求到来前,自动触发
request_finished            # 请求结束后,自动触发
got_request_exception       # 请求异常后,自动触发
Test signals
setting_changed             # 使用test测试修改配置文件时,自动触发
template_rendered           # 使用test测试渲染模板时,自动触发
Database Wrappers
connection_created          # 创建数据库连接时,自动触发

对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception
from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate
from django.test.signals import setting_changed
from django.test.signals import template_rendered
from django.db.backends.signals import connection_created

def callback(sender, **kwargs):
print("xxoo_callback")
print(sender,kwargs)

xxoo.connect(callback)    # xxoo指上述导入的内容

例子:
from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs):
print("Request finished!")

2.自定义信号
a. 定义信号
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

b. 注册信号
def callback(sender, **kwargs):
print("callback")
print(sender,kwargs)

pizza_done.connect(callback)

c. 触发信号
from 路径 import pizza_done

pizza_done.send(sender='seven',toppings=123, size=456)

例子请求后打印一行数据: 配置在urls.py一层目录下面的__init__.py文件中
from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception

from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate

from django.test.signals import setting_changed
from django.test.signals import template_rendered

from django.db.backends.signals import connection_created

def test(sender, **kwargs):
print("request_finished.222")
print(sender, kwargs)

request_started.connect(test)    #请求开始时打印
request_finished.connect(test)    #请求结束后打印
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  缓存 中间件 信号