Django2:Web项目开发入门笔记(24)

767次阅读
没有评论

这一篇教程,我们一起来了解Django的上下文处理器(Context Processor)和中间件(Middleware)。

对于这两块内容,我们最好先了解概念和原理,才能比较好的去应用它们。

一、上下文处理器(Context Processor)

上下文处理器也称作上下文渲染器。

我个人认为处理比渲染更容易理解,而且英文中“Processor”的意思是处理,“Render”的意思是渲染。

但是称为上下文渲染器也有道理,渲染更接近于使用场景。

Django中的Context Processor主要是应用于模板,完成页面的绘制的一些处理,也就是所说的页面渲染。

还有,上下文又是什么?

这个概念,感觉很难懂。

从语文的角度来说,上下文是语境;

同一句话,在不同的语境中,会有不同的意思。

例如,ipipgo考试成绩100分,爸爸说“干得漂亮”,这是表扬的意思。

而ipipgo考试成绩0分,爸爸说“干得漂亮”,这是讽刺的意思。

所以,同样的一句话,我们需要和上文联系到一起才能明白真正的意思。

从计算机编程角度来说,上下文是环境。

也就是说,同一段处理程序对于不同的环境,反馈出不同的处理结果。

借用网上的一个例子:用户访问站点的时候,站点的所有页面上都要能够显示这个用户自己的IP地址。

这样的功能,我们需要从请求(request)中获取到访问用户的IP地址,然后呈现到页面中。

也许大家能够想到,我们可以在每个页面对应的视图函数中进行这个处理,但是未免太过麻烦。

最好的方式是将处理过程定义一次,就能够在每个页面中使用。

此时,我们可以通过自定义一个上下文处理器帮助我们完成。

面对不同来源的用户通过同一个处理器完成页面上不同IP地址的渲染。

1、创建上下文处理器

在项目文件夹(“wsgi.py”所在的文件夹)新建一个文件“context_processor.py”。

在这个文件中添加获取用户IP地址的代码。

示例代码:

def getuserip(request):
    ip = request.META['REMOTE_ADDR']
    if ip == '127.0.0.1':
        return {'user_type': '本机用户'}
    return {'user_type': '外部用户(%s)' % ip}

注意:上下文处理器必须返回一个字典。

2、将上下文处理器添加到模板设置

打开文件“settings.py”,在模板设置中添加处理器中的函数。

TEMPLATES = [
    {
        ...省略部分代码...
        'OPTIONS': {
            'context_processors': [
                ...省略部分代码...
                <strong>'MyProject.context_processor.getuserip'</strong>
            ],
        },
    },
]

上方代码中,红色部分为新增代码。

3、在页面模板中添加标记

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
当前访问用户:<strong>{{ user_type }}</strong>
</body>
</html>

完成上述代码后,Django调用模板时会先通过上下文处理器进行处理,并将处理后返回的数据字典传入模板,通过模板标记获取数据。

此时,我们就可以打开开发服务器,进行访问测试了。

注意:如果需要允许外部访问,需要监听所有IP地址,服务器启动命令为:runserver 0.0.0.0:端口号,也可以简写为runserver 0:端口号(Win10无效)

本机访问结果:

Django2:Web项目开发入门笔记(24)

外部访问结果:(例如手机)

Django2:Web项目开发入门笔记(24)

二、中间件(Middleware)

中间件,我们需要搞清楚它在什么中间,起到什么作用?

根据官方文档的说法,中间件是请求(request)与响应(response)之间的钩子(hooks)框架。

…又多了个钩子。

个人理解钩子实际上就是挂在主程序上的监控程序,当主程序运行中满足了钩子的触发条件时,执行钩子的处理程序。

Django2:Web项目开发入门笔记(24)

在官方文档中,给出的中间件示例非常简单直观,并且包含了两种写法。

1、以函数的形式定义中间件。

示例代码:

<span class="k">def</span> <span class="nf">simple_<span class="highlighted">middleware</span></span><span class="p">(</span><span class="n">get_response</span><span class="p">):</span>
    <span class="c1"># One-time configuration and initialization.</span>

    <span class="k">def</span> <span class="nf"><span class="highlighted">middleware</span></span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
        <span class="c1"># Code to be executed for each request before</span>
        <span class="c1"># the view (and later <span class="highlighted">middleware</span>) are called.</span>

        <span class="n">response</span> <span class="o">=</span> <span class="n">get_response</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>

        <span class="c1"># Code to be executed for each request/response after</span>
        <span class="c1"># the view is called.</span>

        <span class="k">return</span> <span class="n">response</span>

    <span class="k">return</span> <span class="n"><span class="highlighted">middleware</span></span>

2、以类的形式定义中间件

<span class="k">class</span> <span class="nc">Simple<span class="highlighted">Middleware</span></span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">get_response</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">get_response</span> <span class="o">=</span> <span class="n">get_response</span>
        <span class="c1"># One-time configuration and initialization.</span>

    <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="c1"># Code to be executed for each request before</span>
        <span class="c1"># the view (and later <span class="highlighted">middleware</span>) are called.</span>

        <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_response</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>

        <span class="c1"># Code to be executed for each request/response after</span>
        <span class="c1"># the view is called.</span>

        <span class="k">return</span> <span class="n">response</span>

那么,中间件怎么使用?能起到什么样的作用呢?

依然通过举例说明。

例如,我们发布的项目只允许本机和指定ip访问,不允许外部其他地址的设备访问,就可以通过中间件来实现。

首先,创建一个中间件文件“middleware.py”,并定义访问限制的中间件。

这个文件可以创建一个新的Package进行存放,例如:MW。

示例代码:

from django.http import HttpResponseForbidden

class AaccessRestrictionMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response
        self.wite_ip = ['127.0.0.1', '192.168.31.18']  # 初始化ip地址白名单

    def __call__(self, request):
        ip = request.META['REMOTE_ADDR']  # 获取访问用户的ip
        if ip not in self.wite_ip:  # 如果ip不在白名单中
            return HttpResponseForbidden('您被禁止访问!')  # 返回响应
        response = self.get_response(request)
        return response

然后,我们打开文件“settings.py”,在中间件设置中添加中间件的类。

示例代码:

MIDDLEWARE = [
    'MW.middleware.AaccessRestrictionMiddleware',
    ...省略其他中间件...
]

通过以上操作,我们就可以限制只有IP白名单中的用户才能够访问我们的项目。

中间件比较像游戏的外挂程序,游戏主程序的执行过程中一旦满足触发外挂的情形出现,外挂就会执行相应的处理。但是,外挂并不会改变主程序,当我们不需要外挂的时候,只需要移除外挂程序,主程序依然能够正常的执行。

神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试

相关文章:

版权声明:wuyou2023-01-06发表,共计3077字。
新手QQ群:570568346,欢迎进群讨论 Python51学习