django中间件的使用

摘要:
中间件实际上是django中的一个类。在请求到达并结束后,django将根据自己的规则在适当的时间在中间件中执行相应的方法。MIDDLEWARE=['django.MIDDLEWARE.security.SecurityMiddleware','django.contrib.sessions.MIDDLEWARE.SessionMiddleware','django.midleware.common.CommonMiddleware‘,'django MIDDLEWARE.csrf.CsrfViewMiddleware’,'djanga.contrib.auth.MIDDLEWARE.AuthenticationMiddleware`,'djangon.contrib.messages.MIDDLEWARE‘、'django.midleware.clickjacking.XFrameOptionsMiddleware'注册功能,我们通常做一个中间件。当用户登录失败时,他或她将返回登录页面。

1.创建中间件

在django项目的settings模块中,有一个MIDDLEWARE_CLASSES变量,其中每一个元素就是一个中间件。中间件其实就是django中的一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

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',
]

我们在做登录注册功能时一般都会做一个中间件,当用户登录失败时就会返回登录页面。这样就不用在每个方法中验证cooki了(不要重复代码)。
中间件一般放在utils文件中(大家都这么做),我们接着前两天的登录注册功能的代码改写,首先在项目文件下创建一个utils文件夹,在其下面写中间件。

class AuthMiddleWare(MiddlewareMixin):
    def process_request(self, request):
        #  同意验证登录
        #  return None 或者不写
        if request.path == '/uauth/login/' or request.path == '/uauth/regist/':
            return None
        ticket = request.COOKIES.get('ticket')
        if not ticket:
            return HttpResponseRedirect('/uauth/login/')
        users = Users.objects.filter(u_ticket=ticket)
        if not users:
            return HttpResponseRedirect('/uauth/login/')
        request.user = users[0]

上面代码中的process_request是中间件的一种方法。中间件有五种方法,如下图:
这里写图片描述

2.注册中间件

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’,
‘utils.UserAuthMiddleWare.AuthMiddleWare’,
]

3.方法改写

在创建中间件过后就不需要在方法中对cookie进行验证了,所以我们对方法进行改写:

def regist(request):
    if request.method == 'GET':
        return render(request, 'register.html')
    if request.method == 'POST':
        # 注册
        name = request.POST.get('name')
        password = request.POST.get('password')
        password = make_password(password)
        Users.objects.create(u_name=name,
                             u_password=password)
        return HttpResponseRedirect('/uauth/login/')


def login(request):
    if request.method == 'GET':
        return render(request, 'day6_login.html')
    if request.method == 'POST':
        # 如果登录成功,绑定参数到cookie中,set_cookie
        name = request.POST.get('name')
        password = request.POST.get('password')
        if Users.objects.filter(u_name=name).exists():
            user = Users.objects.get(u_name=name)
            if check_password(password, user.u_password):
                ticket = ''
                s = 'qwertyuioplkjhgfdsazxcvbnm1234567890'
                for i in range(15):
                    # 获取十五位随机字符串
                    ticket += random.choice(s)
                now_time = int(time.time())
                # time.time()表示从1970.1.1到现在的秒数
                ticket = 'TK_' + ticket + str(now_time)  # 加上时间戳ticket就永远不会重复
                # 绑定令牌到cookie里面
                response = HttpResponseRedirect('/stu/index/')
                # max_age  存活时间/s
                response.set_cookie('ticket', ticket, max_age=600000000)
                # 存在服务段
                user.u_ticket = ticket
                user.save()
                return response
            else:
                return render(request, 'day6_login.html', {'password': '用户密码错误'})
        else:
            return render(request, 'day6_login.html', {'name': '用户不存在'})

def logout(request):
    if request.method == 'GET':
        response = HttpResponseRedirect('/uauth/login/')
        response.delete_cookie('ticket')
        return response

另外我们在提交表单的时候要在表单里面加上{% csrf_token %},它提供了不被跨站攻击的保护。

4.加载静态文件

我们可以通过加载静态文件来对我们的登录注册页面进行渲染,获得更好的用户体验。

首先我们要创建静态文件夹,在这个文件夹中要包含所有对页面进行渲染需要的元素。(我这里用别人写好的)

其次我们要在项目文件下的setting中进行改写,使页面能读取整个静态文件。

#配置静态文件
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

这样我们再次输入登录的地址就会看到一个好看的页面了
这里写图片描述

5.上传图片

我们在注册网站时,有的网站会让我们上传图片,比如头像。那么这是怎么实现的呢。
首先我们在写注册信息时就要写入上传图片的方法。

def addStuInfo(request, stu_id):
    if request.method == 'GET':
        return render(request, 'addStuInfo.html', {'stu_id': stu_id})
    if request.method == 'POST':
        stu_id = request.POST.get('stu_id')
        addr = request.POST.get('addr')
        # 添加头像图片
        img = request.FILES.get('img')
        StudentInfo.objects.create(i_addr=addr, s_id=stu_id, i_image=img)
        return HttpResponseRedirect('/stu/index/')

然后在写页面的时候也要添加上传图片的选项。

<form  action="" method="POST" enctype="multipart/form-data">
    <input type="hidden" value="{{ stu_id }}" name="stu_id">
    地址:<input type="text" name="addr">
    图像:<input type="file" name="img">
    <input type="submit" value="提交">
        {% csrf_token %}
</form>

注意这里为了不让别人也能提交你的表单,我们在每个表单下面都要写{% csrf_token %}

6.创建日志

再做实际项目时,无论是在开发调试的时候,还是上线为用户提供服务以后,都需要保留下一些运行当中必要的信息用于日后的维护和故障的定位。Django中使用Python内建的logging模块做日志的收集。

首先,我们需要创建存放日志的文件夹
LOG_PATH = os.path.join(BASE_DIR, 'log')
# 如果没有log这个文件夹就自动创建
if not os.path.isdir(LOG_PATH):
    os.mkdir(LOG_PATH)
其次就是日志的格式及其信息处理
LOGGING = {
    'version': 1,  # 必须写
    # disable_existing_loggers表示弃用已经存在的日志,True表示弃用,False表示不弃用。
    'disable_existing_loggers': False,  # 不禁用log功能
    # 格式化日志
    'formatters': {
        'default': {
            'format': '%(levelname)s  %(funcName)s  %(asctime)s %(message)s'
        },
        'simple': {
            'format': '%(levelname)s  %(asctime)s %(message)s'
        }
    },
    # 处理信息
    'handlers': {
        'stu_handlers': {
            'level': 'DEBUG',
            # 指定日志文件指定为5M,超过5M重新备份,然后写入新的日志文件
            'class': 'logging.handlers.RotatingFileHandler',
            'maxBytes': 5 * 1024 * 1024,
            # 文件地址
            'filename': '%s/stu_log.txt' % LOG_PATH,
            'formatter': 'default'
        },
        'uauth_handlers': {
            'level': 'DEBUG',
            # 指定日志文件指定为5M,超过5M重新备份,然后写入新的日志文件
            'class': 'logging.handlers.RotatingFileHandler',
            'maxBytes': 5 * 1024 * 1024,
            # 文件地址
            'filename': '%s/uauth_log.txt' % LOG_PATH,
            'formatter': 'simple'
        }
    },
最后传入要处理的信息
    'loggers': {
        'stu': {
            'handlers': ['stu_handlers'],
            'level': 'INFO'
        },
        'auth': {
            'handlers': ['uauth_handlers'],
            'level': 'INFO'
        }
    },
    'filters': {
    }
}

在配置好setting之后,进入到方法中,对需要记录日志的方法写上记录信息。

我这里演示在进入stu/index/页面是记录日志

import logging

logger = logging.getLogger('stu')


def index(request):
    if request.method == 'GET':
        stuinfos = StudentInfo.objects.all()
        logger.info('url:%s method: %s 获取学生信息成功' % (request.path, request.method))
        return render(request, 'index.html', {'stuinfos': stuinfos})

这样在每次进入stu/index/页面就会有一个存放在log文件夹下的stu_log.txt的记录日志,里面记录了每次对方法进行操作时的信息。

20  index  2018-05-03 15:29:59,456 url:/stu/index/ method: GET 获取学生信息成功
20  index  2018-05-03 15:34:19,590 url:/stu/index/ method: GET 获取学生信息成功
20  addStuInfo  2018-05-03 15:35:47,678 url:/stu/addstuInfo/12/ method: POST 添加学生信息成功
20  index  2018-05-03 15:35:47,881 url:/stu/index/ method: GET 获取学生信息成功
INFO  index  2018-05-03 16:04:52,287 url:/stu/index/ method: GET 获取学生信息成功
INFO  index  2018-05-03 16:06:50,751 url:/stu/index/ method: GET 获取学生信息成功

最后说明的是log记录的日志分为四个level:

critical>error>warning>info>dbug

一般来说做运维和开发人员对critical和error特别重视的。

 
阅读更多

免责声明:文章转载自《django中间件的使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CSS 外边距谁动了我的主机? 之活用History命令下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

基于Django+celery二次开发动态配置定时任务 ( 一 )

需求:           前端时间由于开发新上线一大批系统,上完之后没有配套的报表系统、监控,于是乎开发、测试、产品、运营、业务部、财务等等各个部门就跟那饥渴的饿狼一样需要 各种各样的系统数据满足他们。刚开始一天一个还能满足他们,优化脚本之后只要开发提供查询数据的SQL、收件人、执行时间等等参数就可以几分钟写完一个定时任务脚本 ,到后面不知道是不是吃药了...

django项目搭建及Session使用

django+session+中间件 一、使用命令行创建django项目 在指定路径下创建django项目 django-admin startproject djangocommon   在项目目录下  创建app cd djangocommon python manage.py startapp commoncore(django-admin sta...

Python自动化 【第十八篇】:JavaScript 正则表达式及Django初识

本节内容 JavaScript 正则表达式 Django初识 正则表达式 1、定义正则表达式 /.../ 用于定义正则表达式 /.../g 表示全局匹配 /.../i 表示不区分大小写 /.../m 表示多行匹配 JS正则匹配时本身就是支持多行,此处多行匹配只是影响正则表达式^和$,m模式也会使用^$来匹配换行的内容) 1 var pattern...

Python的Django框架

一、Django简介 Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。 Django 是一个开放源代码的 Web 应用框架,由 Python 写成。 Django 遵守 BSD 版权,初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1.0...

Django框架深入了解——Django中的缓存

Django框架深入了解——Django中的缓存 一、Django中的缓存: 前言: ​ 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户访问量很大的时候,每一次的的后台操作,都会消耗很多的服务端资源,所以必须使用缓存来减轻后端服务器的压力. 缓存是将一些常用的数...

Django组件-forms组件

form组件和 ModelForm 和auth模块 和中介模型  form组件 form组件出现的原因 当我们用普通的form表单提交时会刷新页面,如果这个我们表单中的某项填错了,刷新后我们正确的选项也没有了. 传统的form表单需要我们自己亲自校验每一项.工作量太大 Django 中form组件的2大功能:       1 验证(在前端页面显示我们...