• Django中级篇(下)


    中间件

    django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

    MIDDLEWARE_CLASSES = [
        # 'ZHONGJIANJIAN.text.text1Middleware',   #自定义中间件
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    

    中间件中可以定义四个方法,分别是:

    process_request(self,request)
    process_view(self, request, callback, callback_args, callback_kwargs)
    process_template_response(self,request,response)
    process_exception(self, request, exception)
    process_response(self, request, response)
    

    以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户

    djanjo 中间件版本差异报错处理:

    1.9.x版本以下djanjo中间件定义规则

    class CommonMiddleware(object):
        def process_request(self, request):
            return None
     
        def process_response(self, request, response):
            return response
    		
    

    最新的1.10.x版本djanjo中间件定义规则----------不是执行的类下的方法,而是执行MiddlewareMixin对象的__call__方法(方法中调用,process_request等方法)

    from djanjo.utils.deprecation import MiddlewareMixin
    class CommonMiddleware(MiddlewareMixin):
        def process_request(self, request):
            return None
     
        def process_response(self, request, response):
            return response
    

    下面的方法就可以让 中间件 兼容 Django新版本和旧版本------------上面俩种的合并

    __call__ 方法会先调用 self.process_request(request),接着执行 self.get_response(request) 然后调用 self.process_response(request, response)

    try:
        from django.utils.deprecation import MiddlewareMixin  # Django 1.10.x
    except ImportError:
        MiddlewareMixin = object  # Django 1.4.x - Django 1.9.x
     
     
    class SimpleMiddleware(MiddlewareMixin):
        def process_request(self, request):
            pass
     
        def process_response(request, response):
            pass
    

    新版本中 django.utils.deprecation.MiddlewareMixin 的 源代码 如下:

    class MiddlewareMixin(object):
        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
    

    功效:

    比如我们要做一个 拦截器,比如统计一分钟访问页面数,太多就把他的 IP 加入到黑名单 BLOCKED_IPS,发现有恶意访问网站的人,就拦截他!

    class BlockedIpMiddleware(object):
        def process_request(self, request):
            if request.META['REMOTE_ADDR'] in getattr(settings, "BLOCKED_IPS", []):
                return http.HttpResponseForbidden('<h1>Forbidden</h1>')
    

    中间件生命周期(1.9.x版本以下):

    1>正常情况(有俩个中间件的情况

    process_request1---->process_request2---->process_view1------process_view2----->url---->views---> process_response2----->process_response1

    2>在任意一个process_request中只要有return直接跳到process_response

    process_request1---->process_request2----> process_response2----->process_response1

    3>如果返回值中有render的话走process_template_response

    process_request1---->process_request2---->process_view1------process_view2----->url---->views--->process_template_response2---->

    process_template_response1--->process_response2----->process_response1

    4>views中出现错误的时候走process_exceptionprocess_response

    process_request1---->process_request2---->process_view1--->process_view2----->url---->views---> process_exceptionprocess_response2--->

    process_exceptionprocess_response1

    中间件生命周期(1.10.x版本及以上): 

    和1.9.x版本以下相比,不同点在于,当request中出现return的时候,直接到最外层的response,而不经过里层的response

    自定义中间件

    1、创建中间件类

    class RequestExeute(object):
    
        def process_request(self,request):
    
            pass
    
        def process_view(self, request, callback, callback_args, callback_kwargs):
    
            i =1
    
            pass
    
        def process_exception(self, request, exception):
    
            pass
          
        def process_response(self, request, response):
    
            return response
    

    2、注册中间件

    MIDDLEWARE_CLASSES = (
    
        'django.contrib.sessions.middleware.SessionMiddleware',
    
        'django.middleware.common.CommonMiddleware',
    
        'django.middleware.csrf.CsrfViewMiddleware',
    
        'django.contrib.auth.middleware.AuthenticationMiddleware',
    
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    
        'django.contrib.messages.middleware.MessageMiddleware',
    
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    
        'wupeiqi.middleware.auth.RequestExeute',
    
    )
    

    缓存

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

    Django中提供了6种缓存方式:

    • 开发调试
    • 内存
    • 文件
    • 数据库
    • Memcache缓存(python-memcached模块)
    • Memcache缓存(pylibmc模块)

    1、配置

    a、开发调试

     开发调试

    b、内存

     内存

    c、文件

     文件

    d、数据库

     View Code

    e、Memcache缓存(python-memcached模块)

     Memcache缓存(python-memcached模块)

    f、Memcache缓存(pylibmc模块)

     Memcache缓存(pylibmc模块)

    2、应用

    a. 全站使用

     全站使用

    b. 单独视图缓存

     View Code

    c、局部视图使用

     局部

    信号

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

    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内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

     View Code
     View Code

    ----注册的时候我们可以给上面的代码放到我们创建的project下的__init__.py文件中(或新建一.py文件,最后在__init__中导入)就注册成功了

    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)
    

    由于内置信号的触发者已经集成到Django中,所以其会自动调用,而对于自定义信号则需要开发者在任意位置触发。

    序列化

     关于Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的为Json格式。

    1、serializers

    from django.core import serializers
    
    ret = models.BookType.objects.all()
    
    data = serializers.serialize("json", ret)
    

    2、json.dumps

    import json
    
    #ret = models.BookType.objects.all().values('caption')
    
    ret = models.BookType.objects.all().values_list('caption')
    
    ret=list(ret)
    
    result = json.dumps(ret)
    

    由于json.dumps时无法处理datetime日期,所以可以通过自定义处理器来做扩展,如:

    import json
    from datetime import date
    from datetime import datetime
    
    class CJsonEncoder(json.JSONEncoder):
        def default(self, obj):
            if isinstance(obj, datetime.datetime):
                return obj.strftime('%Y-%m-%d %H:%M:%S')
            elif isinstance(obj, date):
                return obj.strftime("%Y-%m-%d")
            else:
                return json.JSONEncoder.default(self, obj)
    
    用法 : json.dumps(yourdatetimeobj, cls=CJsonEncoder)  
    

    分页

    一、Django内置分页

    Paginator

    二、自定义分页

    分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该在数据库表中的起始位置。

    1、设定每页显示数据条数

    2、用户输入页码(第一页、第二页...)

    3、根据设定的每页显示条数和当前页码,计算出需要取数据表的起始位置

    4、在数据表中根据起始位置取值,页面上输出数据


    需求又来了,需要在页面上显示分页的页面。如:[上一页][1][2][3][4][5][下一页]

    1、设定每页显示数据条数

    2、用户输入页码(第一页、第二页...)

    3、设定显示多少页号

    4、获取当前数据总条数

    5、根据设定显示多少页号和数据总条数计算出,总页数

    6、根据设定的每页显示条数和当前页码,计算出需要取数据表的起始位置

    7、在数据表中根据起始位置取值,页面上输出数据

    8、输出分页html,如:[上一页][1][2][3][4][5][下一页]

     分页

    总结,分页时需要做三件事:

    • 创建处理分页数据的类
    • 根据分页数据获取数据
    • 输出分页HTML,即:[上一页][1][2][3][4][5][下一页]

    文件上传

    a、自定义上传

    def upload_file(request):
        if request.method == "POST":
            obj = request.FILES.get('fafafa')
            f = open(obj.name, 'wb')
            for chunk in obj.chunks():
                f.write(chunk)
            f.close()
        return render(request, 'file.html')
    

    b、Form上传文件实例

     View Code
     View Code
     View Code
  • 相关阅读:
    软件工程第一次作业(2)
    软件工程第一次作业
    TR111与STUN
    定制自己的ubuntu 镜像文件 (remastersys, respin, USB live CD)
    上层认证的安全协议 __〈无线局域网安全务实:WPA与802.11i〉读书笔记
    接入控制层的安全协议 __〈无线局域网安全务实:WPA与802.11i〉读书笔记
    WEP 协议__<无线局域网安全务实:WPA与802.11i〉读书笔记
    Python re模块中search与match的区别
    python中如何使用shell命令, 及python 与shell 中的变量相互通信
    sed命令简介及在sed命令中使用变量的方法
  • 原文地址:https://www.cnblogs.com/yezuhui/p/6853418.html
Copyright © 2020-2023  润新知