基于django中间件的编程思想

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

那么我们可以尝试着使用django中间件的这种思想,来实现 这种功能.

前期准备

现在有个需求, 要实现一个群发信息的功能,通过邮件\短信\微信 通知信息.

实现:

先建两个文件:

# notify.py
def send_email(content):
    print(f'邮件通知:{content}')


def send_msg(content):
    print(f'短信通知:{content}')


def wechat(content):
    print(f'微信通知:{content}')
    
    
    
from notify import *

def send_all(content):
    send_email(content)
    send_msg(content)
    wechat(content)

if __name__ == '__main__':
    send_all('版本更新')

这样就基本实现了初步的功能

importlib模块介绍

# lib文件夹下a.py
name = '你好啊'

# b.py
import importlib  

res = 'lib.aaa'   # 通过字符串的形式导入模块
md = importlib.import_module(res)  # 相当于 from lib import aaa
# 注意: 字符串的最小单位是文件,不能是文件里面的名字
print(md.name)

基于django中间件的编程思想

# notify文件夹下 __init__.py
import settings
import importlib


def send_all(content):
    for path in settings.NOTIFY_LIST:   # 'notify.email.Email'
        module_path, cls_name = path.rsplit('.', maxsplit=1)
        md = importlib.import_module(module_path)   # from notify import Email
        cls = getattr(md, cls_name)     # 获取到文件中类的名字
        obj = cls()
        obj.send(content)
        
        
        
# email.py
class Email(object):
    def __init__(self):
        pass     # 这里写前期的准备
    
    def send(self, content):
        print(f'邮箱通知:{content}')


# msg.py
class Msg(object):
    def __init__(self):
        pass
    
    def send(self, content):
        print(f'短信通知:{content}')


# wechat.py
class Wechat(object):
    def __init__(self):
        pass
    
    
    def send(self, content):
        print(f'微信通知:{content}')


# settings.py

NOTIFY_LIST = [
    'notify.email.Email',
    'notify.msg.Msg',
    'notify.wechat.Wechat'
]

# start.py
from notify import *


send_all('我很不好')

django中settings源码

  1. Django中有两个配置文件,一个内部全局的,一个用户自定义
  2. 如果用户配置了,就使用该配置,否则使用内部全局设置

实现思路:先加载全局配置给对象设置,然后在加载局部配置 再给对象设置,一旦有重复的项 后者覆盖前者

配置文件的插拔式设计

基于django中配置文件的形式设计

目录设计

# conf文件夹下 settings.py
NAME = '我是暴露给用户的自定义配置'

# global_settings.py
NAME = '我是全局配置文件'

# lib > conf下的__init__.py
import os
import importlib
from lib.conf import global_settings


class Settings(object):
    def __init__(self):
        for name in dir(global_settings):
            if name.isupper():
                setattr(self, name, getattr(global_settings, name))

        # 获取暴露给用户的配置文件的 字符串路径
        module_path = os.environ.get('xxx')
        md = importlib.import_module(module_path)
        for name in dir(md):
            if name.isupper():
                k = name
                v = getattr(md, name)
                setattr(self, k, v)


settings = Settings()



# start.py

import os
import sys

sys.path.append(os.path.dirname(__file__))

if __name__ == '__main__':
    os.environ['xxx'] = 'conf.settings'
    from lib.conf import settings

    print(settings.NAME)
posted @ 2019-12-05 22:11  SetCreed  阅读(196)  评论(0编辑  收藏  举报