zoukankan      html  css  js  c++  java
  • 17 django中间件

    django中间件

    中间件就是中间商,你从厂家买东西,经过中间商的协调,拿到自己想要的东西,显然方便了很多,但是也存在一定性能问题,因为不是直接和服务器打交道,而是通过一层层的中间商。

    直接上代码,包含两个应用

      1 """
      2 Django settings for middleware project.
      3 
      4 Generated by 'django-admin startproject' using Django 2.2.3.
      5 
      6 For more information on this file, see
      7 https://docs.djangoproject.com/en/2.2/topics/settings/
      8 
      9 For the full list of settings and their values, see
     10 https://docs.djangoproject.com/en/2.2/ref/settings/
     11 """
     12 
     13 import os
     14 
     15 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
     16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
     17 
     18 
     19 # Quick-start development settings - unsuitable for production
     20 # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
     21 
     22 # SECURITY WARNING: keep the secret key used in production secret!
     23 SECRET_KEY = '*k9n@iw!c6dsh_wdw!tc+v^4d(_k!v_(^j-g$^j@^e=#$w1vr8'
     24 
     25 # SECURITY WARNING: don't run with debug turned on in production!
     26 DEBUG = True
     27 
     28 ALLOWED_HOSTS = []
     29 
     30 
     31 # Application definition
     32 
     33 INSTALLED_APPS = [
     34     'django.contrib.admin',
     35     'django.contrib.auth',
     36     'django.contrib.contenttypes',
     37     'django.contrib.sessions',
     38     'django.contrib.messages',
     39     'django.contrib.staticfiles',
     40     'middle_app01',
     41 ]
     42 
     43 MIDDLEWARE = [
     44     'django.middleware.security.SecurityMiddleware',
     45     'django.contrib.sessions.middleware.SessionMiddleware',
     46     'django.middleware.common.CommonMiddleware',
     47     'django.middleware.csrf.CsrfViewMiddleware',
     48     'django.contrib.auth.middleware.AuthenticationMiddleware',
     49     'django.contrib.messages.middleware.MessageMiddleware',
     50     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     51     'middlewares.AuthLimit',
     52     'middlewares.IpLimitMiddleWare',
     53     'middlewares.MdOne',
     54     'middlewares.MdTwo',
     55 ]
     56 
     57 ROOT_URLCONF = 'middleware.urls'
     58 
     59 TEMPLATES = [
     60     {
     61         'BACKEND': 'django.template.backends.django.DjangoTemplates',
     62         'DIRS': [os.path.join(BASE_DIR, 'templates')],
     63         'APP_DIRS': True,
     64         'OPTIONS': {
     65             'context_processors': [
     66                 'django.template.context_processors.debug',
     67                 'django.template.context_processors.request',
     68                 'django.contrib.auth.context_processors.auth',
     69                 'django.contrib.messages.context_processors.messages',
     70             ],
     71         },
     72     },
     73 ]
     74 
     75 WSGI_APPLICATION = 'middleware.wsgi.application'
     76 
     77 
     78 # Database
     79 # https://docs.djangoproject.com/en/2.2/ref/settings/#databases
     80 
     81 # DATABASES = {
     82 #     'default': {
     83 #         'ENGINE': 'django.db.backends.sqlite3',
     84 #         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
     85 #     }
     86 # }
     87 
     88 
     89 # Password validation
     90 # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
     91 
     92 AUTH_PASSWORD_VALIDATORS = [
     93     {
     94         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
     95     },
     96     {
     97         'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
     98     },
     99     {
    100         'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    101     },
    102     {
    103         'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    104     },
    105 ]
    106 
    107 
    108 # Internationalization
    109 # https://docs.djangoproject.com/en/2.2/topics/i18n/
    110 
    111 LANGUAGE_CODE = 'en-us'
    112 
    113 TIME_ZONE = 'UTC'
    114 
    115 USE_I18N = True
    116 
    117 USE_L10N = True
    118 
    119 USE_TZ = True
    120 
    121 
    122 # Static files (CSS, JavaScript, Images)
    123 # https://docs.djangoproject.com/en/2.2/howto/static-files/
    124 
    125 STATIC_URL = '/static/'
    126 STATICFILES_DIRS = [
    127     os.path.join(BASE_DIR, 'statics')
    128 ]
    129 
    130 LOGIN_URL = '/app01/login/'
    131 
    132 DATABASES = {
    133     'default': {
    134         'ENGINE': 'django.db.backends.mysql',
    135         'NAME':'auth',# 要连接的数据库,连接前需要创建好
    136         'USER':'root',# 连接数据库的用户名
    137         'PASSWORD':'root',# 连接数据库的密码
    138         'HOST':'127.0.0.1',# 连接主机,默认本级
    139         'PORT':3306 #  端口 默认3306
    140     }
    141 }
    142 
    143 LOGGING = {
    144     'version': 1,
    145     'disable_existing_loggers': False,
    146     'handlers': {
    147         'console':{
    148             'level':'DEBUG',
    149             'class':'logging.StreamHandler',
    150         },
    151     },
    152     'loggers': {
    153         'django.db.backends': {
    154             'handlers': ['console'],
    155             'propagate': True,
    156             'level':'DEBUG',
    157         },
    158     }
    159 }
    12 django组件中间件middlewaremiddlewaresettings.py
    from django.urls import path
    from middle_app01 import views
    
    urlpatterns = [
        path('index/', views.index),
        path('login/', views.login),
        path('secret/', views.secret),
    ]
    12 django组件中间件/middleware/middle_app01/urls.py
     1 from django import forms
     2 from django.forms import widgets
     3 from django.core.exceptions import ValidationError
     4 from django.contrib.auth.models import User
     5 
     6 
     7 name_widget = widgets.TextInput(attrs={'class':'form-control'})
     8 pwd_widget = widgets.PasswordInput(attrs={'class':'form-control'})
     9 
    10 
    11 class Form(forms.Form):
    12     name = forms.CharField(min_length=4, max_length=16, widget=name_widget, label='用户名')
    13     pwd = forms.CharField(min_length=4, max_length=16, widget=pwd_widget, label='密码')
    14     email = forms.EmailField(widget=name_widget, label='邮箱')
    15 
    16     def clean_name(self):
    17         val = self.cleaned_data.get('name')
    18         res = User.objects.filter(username=val).exists()
    19         if not res:
    20             return val
    21         else:
    22             raise ValidationError('用户名已存在!')
    23 
    24 
    25 class LoginForm(forms.Form):
    26     name = forms.CharField(min_length=4, max_length=16, widget=name_widget, label='用户名')
    27     pwd = forms.CharField(min_length=4, max_length=16, widget=pwd_widget, label='密码')
    12 django组件中间件/middleware/middle_app01/myforms.py

    12 django组件中间件/middleware/middle_app01/views.py   视图函数

     1 from django.shortcuts import render, HttpResponse, redirect
     2 from django.contrib import auth
     3 from middle_app01.myforms import LoginForm
     4 
     5 # Create your views here.
     6 
     7 
     8 def index(request):
     9     print('----------------------> 视图函数给出的真实响应')
    10     return render(request, 'index.html')
    11 
    12     # 视图函数出错 测试 process_exception
    13     # return render(request, 'indexasdfadf.html')
    14 
    15 
    16 def secret(request):
    17     return render(request, 'secret.html',locals())
    18 
    19 
    20 def login(request):
    21     if request.method == 'POST':
    22         form = LoginForm(request.POST)
    23         if form.is_valid():
    24             print(form.cleaned_data)
    25             username = form.cleaned_data.get('name')
    26             pwd = form.cleaned_data.get('pwd')
    27             user = auth.authenticate(username=username, password=pwd)
    28             if user:
    29                 auth.login(request, user)
    30                 next_url = request.GET.get('next', '/app01/index')
    31                 return redirect(next_url)
    32             else:
    33                 error = '用户名或密码错误!'
    34                 return render(request, 'login.html', locals())
    35         else:
    36             print(form.cleaned_data)
    37             print(form.errors)
    38             return render(request, 'login.html', locals())
    39     else:
    40         form = LoginForm()
    41         return render(request, 'login.html', locals())

    12 django组件中间件middlewaremiddlewares.py    自己定义的中间件     

     1 from django.utils.deprecation import MiddlewareMixin
     2 from django.shortcuts import HttpResponse, redirect
     3 from middleware import settings
     4 import time
     5 
     6 
     7 '''
     8 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。
     9 因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。
    10 如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。
    11 可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。
    12 '''
    13 
    14 
    15 class MdOne(MiddlewareMixin):
    16 
    17     # 当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,
    18     # 在依次穿过中间件,这个时候是process_response,最后返回给请求者。
    19     def process_request(self, request):
    20         ip_black_lis = ['127.0.0.1']
    21         print("----------------------> 请求到达MdOne.process_request")
    22         ip = request.META.get('REMOTE_ADDR')
    23         # 请求到达中间件process_request,如果process_request函数有return,那么将不再继续按正常的流程走到视图函数
    24         # 而是直接返回数据给客户端(),如之前是  A->B->C->视图函数  假如B中发生return,直接返回数据 B->A->客户端
    25         # if ip in ip_black_lis:
    26         #     return HttpResponse('ip在黑名单内,请求中断!')
    27 
    28     # 当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数。
    29     # 最后通过process_response依次返回到达用户。
    30     def process_view(self, request, callback, callback_args, callback_kwargs):
    31         print("----------------------> 请求到达MdOne.process_view")
    32         # process_view如果有返回值,会越过其他的process_view以及视图函数,但是所有的process_response都还会执行。
    33         # return HttpResponse('ojbk!')
    34 
    35         # 还可以直接调用视图函数
    36         # response = callback(request, *callback_args, **callback_kwargs)
    37         # return response
    38 
    39     # 当视图函数报错时,执行这个函数,注意这里已经到达了视图函数,开始网上冒泡,所以这里先答应 MdTwo的process_exception
    40     # HttpResponse('内部有误!') 返回给客户端,如果在 MdTwo 中有返回,则跳过 MdOne 的 MdTwo的process_exception 直接到 MdTwo的process_response
    41     def process_exception(self, request, exception):
    42         print("----------------------> 当视图函数出错MdOne.process_exception")
    43         # return HttpResponse('内部有误!')
    44 
    45     def process_response(self, request, response):
    46         print("----------------------> 返回达到MdOne.process_response")
    47         return response
    48 
    49 
    50 class MdTwo(MiddlewareMixin):
    51 
    52     def process_request(self, request):
    53         print("----------------------> 请求到达MdTwo.process_request")
    54 
    55     def process_view(self, request, callback, callback_args, callback_kwargs):
    56         print("----------------------> 请求到达MdTwo.process_view")
    57 
    58     def process_exception(self, request, exception):
    59         print("----------------------> 当视图函数出错MdTwo.process_exception")
    60         return HttpResponse('内部有误!')
    61 
    62     def process_response(self, request, response):
    63         print("----------------------> 返回达到MdTwo.process_response")
    64         return response
    65 
    66 
    67 ip_pool = {}
    68 # Django中间件限制用户每分钟访问次数不超过10次,一般用于反爬
    69 class IpLimitMiddleWare(MiddlewareMixin):
    70 
    71     def time_filter(self, val):
    72         return time.time() - val < 60
    73 
    74     def process_request(self, request):
    75         ip = request.META.get('REMOTE_ADDR')
    76         if ip_pool.get(ip):
    77             ip_pool[ip] = list(filter(self.time_filter, ip_pool[ip]))
    78             ip_pool[ip].append(time.time())
    79         else:
    80             ip_pool[ip] = [time.time()]
    81         print(ip_pool)
    82         if len(ip_pool[ip]) > 10:
    83             return HttpResponse("频繁访问,请稍后再试!")
    84 
    85 
    86 # URL访问过滤
    87 # 如果用户访问的是login视图(放过)
    88 # 如果访问其他视图,需要检测是不是有session认证,已经有了放行,没有返回login,这样就省得在多个视图函数上写装饰器了!
    89 class AuthLimit(MiddlewareMixin):
    90 
    91     def process_request(self, request):
    92         path = request.path
    93         print(path)
    94         if path != settings.LOGIN_URL and not request.user.is_authenticated:
    95             new_path = settings.LOGIN_URL + '?next=' + path
    96             return redirect(new_path)

    12 django组件中间件/middleware/templates/login.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>login</title>
     6     <link rel="stylesheet" href="/static/bootstrap.min.css">
     7 </head>
     8 <body>
     9 
    10 <div class="container">
    11     <div class="row">
    12         <div class="col-md-6 col-md-offset-3">
    13             <h4>登录</h4>
    14             <form action="" method="post">
    15                 {% csrf_token %}
    16                 {% for field in form %}
    17                     <div class="form-group">
    18                         <label for="">{{ field.label }}</label>
    19                         {{ field }}
    20                         <span class="pull-right" style="color: red">{{ field.errors.0 }}</span>
    21                     </div>
    22                 {% endfor %}
    23                 <input type="submit" class="btn btn-success">
    24                 <span class="pull-right" style="color: red">{{ error }}</span>
    25             </form>
    26         </div>
    27     </div>
    28 </div>
    29 
    30 </body>
    31 </html>
  • 相关阅读:
    查找目录中同名的文件或者文件夹
    「JOISC 2014 Day1」历史研究 --- 回滚莫队
    CSP2019 —— 今年欢笑复明年,不知退役在眼前
    C++实现,拓展中国剩余定理——解同余方程组(理论证明和代码实现)
    [SDOI2016]征途 —— 斜率优化DP
    codeforces#1215E. Marbles(状压DP)
    浅谈矩阵加速——以时间复杂度为O(log n)的算法实现裴波那契数列第n项及前n之和使用矩阵加速法的优化求法
    C++[Tarjan求点双连通分量,割点][HNOI2012]矿场搭建
    浅谈数学上的矩阵——矩阵的乘法运算的概念及C++上的实现模板
    C++边双缩点,Redundant Paths 分离的路径
  • 原文地址:https://www.cnblogs.com/znyyy/p/11377918.html
Copyright © 2011-2022 走看看