확장 요청 위조 인터셉트 모듈 미들웨어가 인증 -Django -csrf Django- 미들웨어 - 구성된 플러그인 미들웨어 장고 따라이 기능을 구현하는 효과 -09

어제 추가 : 자신의 기록 login_auth은 CBV에 장착 된 장식을 하죠

방법 내부 클래스는 일반적으로 클래스 메소드를 바인딩하거나 방법을 결합 객체, 첫 번째 매개 변수는 클래스 또는 객체 자체 이전 쓰기 장식이 사용하는 매개 변수를 변경해야합니다, 그러나 여기에서 우리는 장고와 함께 우리에게 쓸 수 있습니다 좋은 장식, 변경은 서면 장식을 필요로하지 않습니다

세 가지 방법 ( 가이드 모듈을 기억하십시오 )

from django.utils.decorators import method_decorator

# @method_decorator(login_auth, name='get')  # 第一种, name 参数必须指定
class MyHome(View):
    # @method_decorator(login_auth)  # 第二种, get 和 post 都会被装饰(登录验证)(直接把 dispatch 拿过来,加个装饰器)
    def dispatch(self, request, *args, **kwargs):
        super().dispatch(request, *args, **kwargs)
     
    @method_decorator(login_auth)  # 第三种,直接装饰在单个方法上
    def get(self, request):
        return HttpResponse('get')
    
    def post(self, request):
        return HttpResponse('post')

장고 미들웨어

장고 장고 미들웨어 게이트웨이, 유사합니다 요청 (URL을) 미들웨어 백엔드 장고 얻기 위해 통과해야하는 웹 서비스 게이트웨이 인터페이스 (wsgif 모듈)에 도달하는 미들웨어를 통해 갈 시간이 걸릴 응답

장고 미들웨어는 무엇을 할 수 있습니다

  • 사이트 글로벌 신원 검사를 수행, 액세스 빈도를 제한 권한 (안티 상승)을 확인 한 전반적인 검증이 거의 미들웨어에서 수행 할 수 있습니다에이 관련된 , 그것은 처음에는 미들웨어의 생각입니다

장고 미들웨어 디자인은 논리적, 더 완벽 가장 명쾌하고 간단한 (그것에 플라스크 미들웨어 열등)

모든 요청을 제출 한 후 일시적으로 밖으로 댓글을 달았 CSRF 미들웨어에서이 이동 settings.py에 기록됩니다 왜 우리보다 앞서 완성이 미들웨어는 알

장고 요청 라이프 사이클 *****

미들웨어 urls.py 들어간다 후 (views.py ... 층 진행하여 다음 층)

인기 과학 :

  1. wsgiref 높은 동시성을 견딜 수없는 선이 uwsgi 모듈 (전면 플러스 리버스 프록시 할 nginx를) 후 교체 될 수 있도록,
  • WSGI는 각각 WSGI 및 uwsgi을 의미하고 무엇을

WSGI는 표준 프로토콜, wsgiref이고 uwsgi는 WSGI 프로토콜 기능 모듈을 얻을 수있다

  1. 제 1 중간 층에 가서 요청을 입력하면 데이터베이스에 있는지의 여부 캐시 데이터를 결정
  • 어떤 경우, 직접 데이터를 얻을 요청 돌려줍니다 (이 저장할 수있는 자원, 서버 및 데이터베이스에 대한 압력을 감소)합니다
  • 그렇지 않으면, 우리는 층으로 미들웨어 계층을 갈 것입니다, 다음 구성, views.py을 ... 라우팅 및 반환 된 데이터가 캐시 데이터베이스에 저장됩니다 동안 그래서, 다시 미들웨어 요청의 마지막 층에왔다 한다. (다음 시간 당신은 캐시 데이터베이스 데이터에 직접 얻을 수 있습니다)

라인에 개념의 측면에서 확장에 관한 구체적인 원칙과 다른 게시물을 알고

기본 방법은 아마도 미들웨어로 구성되며,

일곱 개 기본 장고 미들웨어가 있습니다

장고 사용자 정의 자신의 미들웨어 및 사용자에게 노출은 또한 사용자에 다섯 사용자 정의 방식의 미들웨어를 노출 할 수 있습니다 지원

# settings.py 里的七个默认中间件
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.middleware.security.SecurityMiddleware
--> 本质是动态导入(可以看最后面的那个模仿案例) 
# from django.middleware.security import SecurityMiddleware

django.middleware.csrf.CsrfViewMiddleware
--> from django.middleware.csrf import CsrfViewMiddleware
'''

찾을 수 장고 미들웨어는 다섯 사용자 정의 메소드가

# django.middleware.csrf.CsrfViewMiddleware  --> from django.middleware.csrf import CsrfViewMiddleware
class CsrfViewMiddleware(MiddlewareMixin):
    def _accept(self, request):
    def _reject(self, request, reason):
    def _get_token(self, request):
    def _set_token(self, request, response):
    def process_request(self, request):
    def process_view(self, request, callback, callback_args, callback_kwargs):
    def process_response(self, request, response):

# django.middleware.security.SecurityMiddleware  --> django.middleware.security.SecurityMiddleware
class SecurityMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
    def process_request(self, request):
    def process_response(self, request, response):      

# django.contrib.sessions.middleware.SessionMiddleware
class SessionMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
    def process_request(self, request):
    def process_response(self, request, response):
  • 우리는 방법을 마스터해야
  1. process_ 요구 () 메소드
  2. process_ 응답 () 메소드
  • 당신은 방법을 이해할 필요가있다
  1. process_ 뷰 ()
  2. 예외 처리 ()
  3. process_ template_ 응답 ()

미들웨어 실행 순서

대략 같은 장고 요청 라이프 사이클은 그림은 다음과 같은 조건에 의해 영향을받을 수 있습니다

사용자 조작 미들웨어 실행 미들웨어 다른 순서로의 영향을 살펴

시험 아이디어 :

  • settings.py에서 다른 미들웨어 가입, 기본 실행 순서 문의
  • 순서를 실행합니다 반환 HttpResponse에 개체를 다른 미들웨어 process_request 및 process_response 방법에 미치는 영향은 무엇입니까
  • 트리거의 타이밍을 이해하는 다섯 가지 방법

사용자 정의 미들웨어

  1. (전역 또는 내 응용 프로그램에서) 새 폴더 만들기
  2. 클래스를 작성하는 것은 MiddlewareMiXin 클래스를 상속
  3. 내부 (몇 가지 방법에 오)가 필요 쓰는 방법
  4. settings.py에서 미들웨어를 구성해야합니다

코드

mymiddleware / mdd.py 사용자 정의 미들웨어

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse


class MyMdd(MiddlewareMixin):
    def process_request(self, request):
        print('我是第一个中间件里面的process_request方法')

    def process_response(self, request, response):
        print('我是第一个中间件里面的process_response方法')
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print(view_func)
        print(view_args)
        print(view_kwargs)
        print('我是第一个中间件里面的process_view方法')

    def process_exception(self, request, exception):
        print('我是第一个中间件里面的process_exception')

    def process_template_response(self, request, response):
        print('我是第一个中间件里面的process_template_response')
        return response


class MyMdd1(MiddlewareMixin):
    def process_request(self, request):
        print('我是第二个中间件里面的process_request方法')

    def process_response(self, request, response):
        print('我是第二个中间件里面的process_response方法')
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print(view_func)
        print(view_args)
        print(view_kwargs)
        print('我是第二个中间件里面的process_view方法')

    def process_exception(self, request, exception):
        print('我是第二个中间件里面的process_exception')

    def process_template_response(self, request, response):
        print('我是第二个中间件里面的process_template_response')
        return response


class MyMdd2(MiddlewareMixin):
    def process_request(self, request):
        print('我是第三个中间件里面的process_request方法')

    def process_response(self, request, response):
        print('我是第三个中间件里面的process_response方法')
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print(view_func)
        print(view_args)
        print(view_kwargs)
        print('我是第三个中间件里面的process_view方法')

    def process_exception(self, request, exception):
        print('我是第三个中间件里面的process_exception')

    def process_template_response(self, request, response):
        print('我是第三个中间件里面的process_template_response')
        return response

settings.py의 구성

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',
    'mymiddleware.mdd.MyMdd',  # 配置上
    'mymiddleware.mdd.MyMdd1',  # 配置上
    'mymiddleware.mdd.MyMdd2',  # 配置上
]

방법은 알 필요가

process_request

요청하는 경우 구성 파일 실행 미들웨어에 등록 된 settings.py를 차례로

  • 이 방법은 미들웨어 아래로, 생략되어 있지 않은 경우
  • 이 방법은 내부에 대한 HttpResponse 객체를 반환하는 경우는, 현재의 미들웨어에서 process_response 방법에서 실행 반환을 켜집니다 다운 후 실행되지 않습니다
  • 실행 순서 : 상단에서
  • 이 방법은 사용자의 권한을 확인하는 사용자의 신원 확인, 액세스 빈도에 제한을 구현할 수있다 ..

당신은 주파수 특성에 따라 액세스를 제한 할 수

process_response

응답 시간을 갖고 (응답 데이터의 전면에 다시 참조 할 수 있기 때문에, 매개 변수 응답이 반환해야합니다) 미들웨어 방식에 등록 된 회전 settings.py 구성 파일에서 실행됩니다

  • 이 방법은 미들웨어 아래로, 생략되어 있지 않은 경우
  • 실행 순서 : 최대 바닥에서
  • 이 방법은 캐싱 메커니즘을 구현하는 데 도움 수 (서버에서 천천히 압력을, 데이터베이스)

당신은 방법을 이해할 필요가있다

process_view

뷰 기능의 성공적인 구현을 라우팅하기 전에 일치는 자동으로 (아래 실행 위에서부터) 트리거

process_exception

보기 기능이 주어지고 , 자동적으로 (위의 실행 아래에서) 트리거

process_template_response

보기 기능을 포함 HttpResponse에 오브젝트 속성 렌더링 반환 객체 또는 등가의 방법을 트리거 TemplateResponse 시간 오브젝트들 (아래에서 위로 수행) 할 때 트리거 또는 지시

def index(request):
    print("我是 index 视图函数")
    def render():
        return HttpRespone('用户最终能够看到的结果')  # ******
    obj = HttpResponse('index')
    obj.render = render  # 返回的 HttpResponse 对象中必须包含 render 属性,才能触发中间件里定义的 process_template_response 方法
    return obj

그는 강조했다 :

미들웨어를 작성할 때 매개 변수가 응답을 가지고로, 한, 우리가 그것을 반환하는 기억해야한다,이 정보는 응답의 전면을 제공하는 것입니다

CSRF의 미들웨어 CSRF

피싱 사이트

원리 : , 동일한 사이트, 숨겨진 상자를 쓰기 숨겨진으로 파티에 돈을 보내

Q : 어떻게 우리의 사용자가 보낸 현재 페이지 요청이 웹 사이트의 우리의 웹 사이트가되지 구별

아이디어를 방지

이 사이트는 사용자의 폼 양식 페이지로 돌아갑니다 비밀리에 임의의 문자열을 박제

요청을 직접 거절하지 않으면 랜덤 문자열이 동일한 것보다 먼저 온다 (403 금지됨)

솔루션

이 값은 위조 될 수 없다 페이지에 넣어 값을 넣어 숨겨진 입력 상자, 문자열 사람들이 사이트를 모르는, 그래서 각 새로 고침, 내부의 값을 업데이트 할 것입니다

장고 구현 {% csrf_token %}

랜덤 문자열은 다음과 같은 특징이 있습니다 :

  • 방문 할 때마다 다른 같은 브라우저
  • 다른 브라우저에서 확실히 동일하지

CSRF에 의해 제출 된 후 요청 검증 데이터

양식 양식

형태는 포스트 요청 양식을 보낼 때, 당신이해야 할 코드의 조각을 작성하는 것입니다해야합니다 {% csrf_token %}, 당신은 코멘트 CSRF 미들웨어가 필요하지 않습니다

아약스 보내기

세 가지 (제 후단 표면에서 분리 될 수있다)

  1. 첫 페이지 쓰기에서 {% csrf_token %}, 데이터의에 입력 키 정보를 얻기 위해, 찾기 위해 태그를 사용하여

  2. AJAX 데이터 값 여기서, 직접 기록 {{ csrf_token }}( data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},)

  3. 공식 문서를 참조하는 것이 좋습니다 페이지에 사용되는 사용자 정의의 js 파일이 자동으로 획득하고 CSRF 검사를 통과하는 JS 스크립트를로드 *****

    • 당신은 JS 파일 JS에 다음 코드를 배치 할 수 있습니다
    // js 代码(一般放在 static 文件夹下)
    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    
    var csrftoken = getCookie('csrftoken');
    
    
    function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    
    $.ajaxSetup({
        beforeSend: function (xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        }
    });
    • 사용 후 배치 <script src="{% static 'setjs.js' %}"></script>라인에 가져 오기를
    • 이 HTML로 작성할 필요가 없습니다 {% csrf_token %}에 아약스 또는 쓰기 {{ csrf_token }}

CSRF 데코레이터 관련을

다른 미들웨어는 또한 다음과 같은 방법을 확인하거나 취소 확인하기 위해 수행 할 수

두 가지 문제

글로벌 웹 사이트가 당신이 (CSRF 미들웨어를 주석 처리되지 않음) CSRF 시간을 확인해야하는 경우, 몇 가지 방법이 과정을 점검 할 필요가 없습니다 있습니까? @csrf_exempt

당신이 (시간 주석 CSRF 미들웨어에서) CSRF 글로벌 웹 사이트를 확인하지 않는 경우, 당신이 처리하는 방법을 확인해야 할 몇 가지가있다?@csrf_protect

단일 기능 CSRF 확인을 취소 할 때 주석 CSRF 미들웨어 : csrf_exempt

FBV

from django.views.decorators.csrf import csrf_exempt

# 全局开启时,局部禁用
@csrf_exempt
def index(request):
  pass

CBV

이 두 가지 방법은 아닌 하나의 메소드에 대한 전역입니다

# CBV比较特殊,不能单独加在某个方法上
# 只能加在类上或dispatch方法上
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt


# @method_decorator(csrf_exempt,name='dispatch')  # 第一种
class Csrf_Token(View):
  @method_decorator(csrf_exempt)  # 第二种
  def dispatch(self,request,*args,**kwargs):
    res = super().dispatch(request,*args,**kwargs)
    return res
  # @method_decorator(csrf_exempt)  # 这里这么写不行!!!
  def get(self,request):
    pass
  def post(self,request):
    pass

단일 기능 검사 설정 CSRF는 CSRF 미들웨어 주석 : csrf_protect

FBV

from django.views.decorators.csrf import csrf_protect


@csrf_protect
def lll(request):
    return HttpResponse('lll')

CBV 변화로 변경해야

그것은 하나이 될 수 있습니다 세계에 대한 세 가지 방법이 있습니다

from django.views.decorators.csrf import csrf_protect

from django.views import View
from django.utils.decorators import method_decorator


# 第一种方式
# @method_decorator(csrf_protect,name='post')  # 有效的
class MyView(View):
    @method_decorator(csrf_protect)  # 第三种方式
    def dispatch(self, request, *args, **kwargs):
        res = super().dispatch(request, *args, **kwargs)
        return res

    def get(self, request):
        return HttpResponse('get')

    # 第二种方式
    # @method_decorator(csrf_protect)  # 有效的
    def post(self, request):
        return HttpResponse('post')

요약 : CSRF 데코레이터 만 csrf_exempt은 CBV를 장식하는 다른 장식은 세 가지 방법으로 할 수 있습니다 특별한 경우이며,

인증 모듈

팁 과학 작은 점 :

  • 결과가 최선의 유형을 확인하기 위해 "문자열"을 인쇄하는 방법입니다 교체, 오브젝트가 재 작성 될 수 있습니다 __str__()방법
  • 장고 관리자 슈퍼 유저 만 입력 할 수 있습니다
  • 방법 인증 모듈을 사용하는 방법은, 그 모듈의 인증을 위해 최선
  • 암호 변경, 그렇지 않으면 무효, 저장 .save ()를 호출해야합니다

장고 인증은 로그인 기능을 할 수있는 내장 테이블을 사용하여

관련 인증 관련 방법

python3 manage.py createsuperuser  # 命令行下创建超级用户(可以拥有登录 django admin 后台管理的权限)

# 查询用户是否存在
user_obj = auth.authenticate(username=username, password=password)  # 数据库中的密码是密文的(该方法不能只传用户名一个参数),返回值要么是对象,要么是 None

# 记录用户状态
auth.login(request, user_obj)  # 登录,会自动存 session
# 优点:只要执行了这一句话,你就可以在后端任意位置通过 request.user 拿到当前登录的用户对象(未登录会报错,AnonymousUser 匿名用户)

# 获取用户对象
request.user  # 用户登录了直接获取用户对象,用户没登录获取到 AnonymousUser 匿名用户

# 判断当前用户是否登录,未登录(AnonymousUser)会返回 False,其他情况下返回 True
request.user.is_authenticated

# 验证用户密码是否正确
is_right = request.user.check_password(old_password)  # 将获取的用户密码,自动加密,然后去数据库中对比(返回布尔值)

# 修改密码
request.user.set_password(new_password)  # 修改密码
request.user.save()  # 需要保存才能生效

# 注销用户
auth.logout(request)  # 等价于 request.session.flush() (删除了 session
表中记录,浏览器 cookie)


# 登录验证装饰器
from django.contrib.auth.decorators import login_required

# @login_required  # 自动校验当前用户是否登录,如果没有登录,(未传参数的情况下)默认跳转到 django 自带的登录页面(还是 404 ?)
# ------ 局部配置
@login_required(login_url='/login/')
def set_password(request):
    pass

# ------ 全局配置(不用在里面写配置了)
# 在 settings.py 中写
LOGIN_URL = '/login/'


# 注册用户
from django.contrib.auth.models import User  # 这就是那张 auth 表
# 创建普通用户
User.objects.create_user(username=username, password=password)
# 创建超级用户
User.objects.create_superuser(username=username, password=password, email='[email protected]')  # 创建超级用户必须传邮箱
# 不能用 User.objects.create(username=username, password=password)  (这样密码没有加密)

핵심 코드

이 app01 / views.py

from django.shortcuts import render, HttpResponse
from django.contrib import auth


def xxx(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 取数据库查询当前用户数据
        # models.User.objects.filter(username=username,password=password).first()
        user_obj = auth.authenticate(username=username, password=password)  # 必须要用 因为数据库中的密码字段是密文的 而你获取的用户输入的是明文
        print(user_obj)
        # print(user_obj)
        # print(user_obj.username)
        # print(user_obj.password)
        # 保存用户状态
        # request.session['user'] = user_obj
        auth.login(request, user_obj)  # 将用户状态记录到session中
        """只要执行了这一句话  你就可以在后端任意位置通过request.user获取到当前用户对象"""
    return render(request, 'xxx.html')


def yyy(request):
    print(request.user)  # 如果没有执行auth.login那么拿到的是匿名用户
    print(request.user.is_authenticated)  # 判断用户是否登录  如果是你们用户会返回False
    # print(request.user.username)
    # print(request.user.password)
    return HttpResponse('yyy')


from django.contrib.auth.decorators import login_required


# 修改用户密码
@login_required  # 自动校验当前用户是否登录  如果没有登录 默认跳转到 一个莫名其妙的登陆页面
def set_password(request):
    if request.method == 'POST':
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        # 先判断原密码是否正确
        is_right = request.user.check_password(old_password)  # 将获取的用户密码 自动加密 然后去数据库中对比当前用户的密码是否一致
        if is_right:
            print(is_right)
            # 修改密码
            request.user.set_password(new_password)
            request.user.save()  # 修改密码的时候 一定要save保存 否则无法生效
    return render(request, 'set_password.html')


@login_required
def logout(request):
    # request.session.flush()
    auth.logout(request)
    return HttpResponse("logout")


from django.contrib.auth.models import User


def register(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user_obj = User.objects.filter(username=username)
        if not user_obj:
            # User.objects.create(username =username,password=password)  # 创建用户名的时候 千万不要再使用create 了
            # User.objects.create_user(username =username,password=password)  # 创建普通用户
            User.objects.create_superuser(username=username, password=password, email='[email protected]')  # 创建超级用户
    return render(request, 'register.html')

사용자 정의 확장 autor 필드

전제 :

settings.py를 추가 구성을 추가

# ... 其他配置
# 告诉 django 不再使用 auth 默认的表  而是使用你自定义的表
AUTH_USER_MODEL = 'app01.Userinfo'  # '应用名.模型表类名'
# ... 其他配置

두 가지 방법

이 app01 / models.py

from django.db import models
from django.contrib.auth.models import AbstractUser


# Create your models here.
# 第一种 使用一对一关系  不考虑


# 第二种方式   使用类的继承
class Userinfo(AbstractUser):
    # 千万不要跟原来表(AbstractUser)中的字段有冲突
    phone = models.BigIntegerField()
    avatar = models.CharField(max_length=32)
    # 别忘了去 settings.py 里配置

다음 단계

데이터베이스 이주 명령을 수행합니다 python3 manage.py makemigrations、python3 manage.py migrate()

이 후, 모든 인증 모듈 기능은 모든 오히려 AUTH_USER를 사용하는 것보다, 생성 한 테이블을 기반으로 (사람들은 더 이상 자동으로 테이블을 만들 수 없음)

장고 미들웨어 구성 기능 플러그 효과를 모방 할 수 있도록

장고 미들웨어 실제로 함수의 클래스가 클래스로 기록 될 수있다, 주석 부분을 실행하지

우리는 (디자인 생각이 너무 배울 나중에 restframework) 미들웨어의 예에 따라 알림 기능을 , 당신은 마이크로 채널 알림, SMS 알림을 보낼 수 있습니다, 마우스 오른쪽 통지

코드 구현

주요 구성 섹션 (배울 수 많은 디자인)

start.py 항목 파일

import notify

notify.send_all('国庆放假了 记住放八天哦')

notify/__init__.py 키 코드 (도입 동적 지식 importlib의 조합, 반사 등)

import settings
import importlib


def send_all(content):
    for path_str in settings.NOTIFY_LIST:  # 1.拿出一个个的字符串   'notify.email.Email'
        module_path, class_name = path_str.rsplit('.', maxsplit=1)  # 2.从右边开始 按照点切一个 ['notify.email', 'Email']
        module = importlib.import_module(module_path)  # from notity import msg/email/wechat
        cls = getattr(module, class_name)  # 利用反射 一切皆对象的思想 从文件中获取属性或者方法 cls = 一个个的类名
        obj = cls()  # 类实例化生成对象
        obj.send(content)  # 对象调方法

settings.py 구성 (기능을 켜거나 끄 여기에서 할 수 있습니다)

NOTIFY_LIST = [
    'notify.email.Email',
    'notify.msg.Msg',
    # 'notify.wechat.WeChat',  # 注释掉了,这个功能就不执行了
    'notify.qq.QQ',
]

기능 확장

그런 다음 각 기능 파일 (개별 파일로 분할 settings.py 플러그 효과 재생) 직접 할 수있다 이러한 코드를 구현하는 파일을 추가하려면이 기능을 추가하기 위해,

/ email.py 통보

class Email(object):
    def __init__(self):
        pass  # 发送邮件需要的代码配置

    def send(self, content):
        print('邮件通知:%s' % content)

/ msg.py 통보

class Msg(object):
    def __init__(self):
        pass  # 发送短信需要的代码配置

    def send(self, content):
        print('短信通知:%s' % content)

/ qq.py 통보

class QQ(object):
    def __init__(self):
        pass  # 发送qq需要的代码准备

    def send(self, content):
        print('qq通知:%s' % content)

통지 / wechat.py

class WeChat(object):
    def __init__(self):
        pass  # 发送微信需要的代码配置

    def send(self, content):
        print('微信通知:%s' % content)
보충 : pycharm 팁

로 이동하는 코드의 현재 위치를 알고 싶어요, 당신은 그림에있는 아이콘을 클릭하면, 빠른 위치, 당신은 디렉토리 구조를 알릴 수 (아마도 바로 볼 수 있습니다)

추천

출처www.cnblogs.com/suwanbin/p/11591887.html