Django学习笔记之自定义中间件的使用(实现简单站内消息)

1、django流程、中间件流程图

 

2、中间件的作用

官方文档所说:Middleware is a framework of hooks into Django’s request/response processing. It’s a light, low-level “plugin” system for globally altering Django’s input or output.(中间件是连接到Django请求/响应处理的框架。它是一个轻量级的、低层次的“插件”系统,用于全局改变Django的输入或输出。)

也就是说,当你想在执行视图前后,对输入输出进行添加或删除某些值,就可以用到中间件。

常见的应用场景就是要对每个请求都获取请求的用户名,或者是想要实现站内消息,如下效果:

首先,设计思路:在数据库中新建一张表用来记录通知的内容、通知的接受者(外键,关联用户表)、通知发出的时间、通知的状态(状态默认为0,表示未读;用户点击阅读后,修改状态为1,表示已读)

因为通知一栏每个页面都会有,而且阅读通知后通知状态就会变成已读,显示的通知个数就变为0,由此可见未读通知个数是随时可变的,所以对于每次请求都需要去数据库中查询,此用户的未读通知个数为多少,再传递给模板显示出来。

由于每个请求都要对输入添加用户名和未读通知个数再传递给视图,所以这用中间件就很简单了。

 

3、中间件的使用

  • 在APP下新建一个py文件,如下middleware.py:

  • 在中间件middleware.py文件中写需要的逻辑函数(从session中获取用户名,然后查询用户表获取此用户ID,再通过用户ID查询通知表该用户通知状态为未读的对象个数,并将查询到的个数写入request中):
from django.utils.deprecation import MiddlewareMixin
from web import models
from rbvc.models import UserInfo


class count_notice_num(MiddlewareMixin):
            def process_request(self,request):
                try:
                    self.username = request.session['username']
                except:
                    return None

                self.user_id = UserInfo.objects.get(username=self.username).id

                self.notice_num = models.Notice.objects.filter(userinfo_id=self.user_id).filter(has_read= 0).count()

                if self.notice_num == 0:
                    self.notice_num = ''

                request.notice_num = self.notice_num
                return None

    由于我们是要在执行视图前添加数据,所以我们需要改写 process_request函数

  • 再于settings.py文件中声明这个中间件的路径:rbvc.middleware.count_notice_num(app名称.文件名.类名或函数名)
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',
    'rbvc.middleware.RBACMiddleware',
    'rbvc.middleware.count_notice_num',
]
  • 接着,改写视图返回模板函数render(新建py文件,名字路径随意,方便复用)
from django.shortcuts import render

def mp_render(request, template, context={}):
    try:
        context['username'] =request.session['username']
        context['notice_num']=request.notice_num
    except:
        pass
    return render(request,template, context)
  • 最后,把视图中原来使用render的地方全部改写成自定义的mp_render(注意使用前,根据上述新建的py文件名字路径导入 mp_render函数)

   所有原来用   return render(request, '***.html',locals())  的,改写成  return mp_render(request, '***.html',locals()) 其余的逻辑不变,即可以完成在原来项目基础上,在每个请求后执行视图前添加用户名、用户未读消息个数,再传递给模板。

            <a class="user-menu right"  href="/notice/list">
                通知
                <i class="fa fa-envelope-o" aria-hidden="true"></i>
                <span class="badge bg-danger">{{ notice_num }}</span>
            </a>

现在模板就能识别 notice_num这个变量了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django中间件Django框架中的一个重要概念,可以在请求和响应之间定义一些处理逻辑。Django提供了一些内置的中间件,比如Session中间件、Csrf中间件等。除了内置的中间件,我们还可以自定义中间件实现一些自定义的逻辑。 自定义中间件的步骤如下: 1. 创建一个Python文件,命名为middleware.py。 2. 定义一个中间件类,继承自django.middleware.BaseMiddleware类,并实现__init__、process_request、process_response方法。 - __init__方法:中间件初始化方法,可以接收Django的settings对象作为参数。 - process_request方法:处理请求前的逻辑,可以对请求进行处理或者拦截请求。 - process_response方法:处理响应后的逻辑,可以对响应进行处理或者拦截响应。 3. 在settings.py文件中配置中间件。 - 在MIDDLEWARE_CLASSES或者MIDDLEWARE中添加自定义中间件的路径。 下面是一个简单的示例: ```python # middleware.py class MyMiddleware: def __init__(self, get_response): self.get_response = get_response def process_request(self, request): # 处理请求前的逻辑 return None def process_response(self, request, response): # 处理响应后的逻辑 return response ``` ```python # settings.py MIDDLEWARE = [ # ... 'myproject.middleware.MyMiddleware', # ... ] ``` 以上示例中,我们定义了一个名为MyMiddleware的中间件类,并实现了process_request和process_response方法。在process_request方法中,我们可以对请求进行处理或者拦截请求;在process_response方法中,我们可以对响应进行处理或者拦截响应。最后,在settings.py文件中添加自定义中间件的路径即可。 需要注意的是,如果你的中间件是一个类而不是一个函数,那么你需要在类的构造函数中接收一个get_response参数,并将其保存在实例变量中。这里的get_response参数是一个可调用对象,它代表着整个Django请求-响应处理过程中的后续处理逻辑。在自定义中间件的process_request或process_response方法中,如果你想要继续执行后续的处理逻辑,就需要调用get_response方法。如果你不调用get_response方法,那么后续的处理逻辑就不会被执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值