zoukankan      html  css  js  c++  java
  • 基于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)
    
  • 相关阅读:
    为什么java的接口的方法是public abstract修饰?为什么属性是public static final 修饰?
    java方法的重载
    java的自增和自减
    html和jsp页面中把文本框禁用,只能读不能写的方法
    JavaScript的数据类型有哪些?
    thinkPHP 框架 delete方法无法删除数据 【已解决】
    Linux shell 数组
    redis cpu占用过高100%,清理病毒事件
    Linux 批量杀掉进程
    记一次宝塔Linux面板磁盘占满,删除文件后空间没有减少的问题
  • 原文地址:https://www.cnblogs.com/setcreed/p/11992377.html
Copyright © 2011-2022 走看看