热门IT资讯网

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

发表于:2024-11-29 作者:热门IT资讯网编辑
编辑最后更新 2024年11月29日,一、form插件django form表单类的字段和插件,字段用于表单验证获取数据,插件用来生成html代码Field required=True, 是否允许为空
一、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.pyfrom django.forms import Formfrom django.forms import fieldsfrom django.forms import widgetsfrom app01 import modelsimport refrom django.core.exceptions import ValidationErrorfrom django.core.validators import RegexValidatorclass 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
三、中间件项目目录下新建目录mdmd目录新建middleware.py文件from django.shortcuts import HttpResponse,redirectclass 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 responseclass 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 responseclass 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_requestprocess_viewprocess_exceptionprocess_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_pageurlpatterns = [    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_finishedfrom django.dispatch import receiver@receiver(request_finished)def my_callback(sender, **kwargs):        print("Request finished!")    2.自定义信号a. 定义信号import django.dispatchpizza_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_finishedfrom django.core.signals import request_startedfrom django.core.signals import got_request_exceptionfrom django.db.models.signals import class_preparedfrom django.db.models.signals import pre_init, post_initfrom django.db.models.signals import pre_save, post_savefrom django.db.models.signals import pre_delete, post_deletefrom django.db.models.signals import m2m_changedfrom django.db.models.signals import pre_migrate, post_migratefrom django.test.signals import setting_changedfrom django.test.signals import template_renderedfrom django.db.backends.signals import connection_createddef test(sender, **kwargs):    print("request_finished.222")    print(sender, kwargs)request_started.connect(test)    #请求开始时打印request_finished.connect(test)    #请求结束后打印


0