어제 추가 : 자신의 기록 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 ... 층 진행하여 다음 층)
인기 과학 :
- wsgiref 높은 동시성을 견딜 수없는 선이 uwsgi 모듈 (전면 플러스 리버스 프록시 할 nginx를) 후 교체 될 수 있도록,
- WSGI는 각각 WSGI 및 uwsgi을 의미하고 무엇을
WSGI는 표준 프로토콜, wsgiref이고 uwsgi는 WSGI 프로토콜 기능 모듈을 얻을 수있다
- 제 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):
- 우리는 방법을 마스터해야
- process_ 요구 () 메소드
- process_ 응답 () 메소드
- 당신은 방법을 이해할 필요가있다
- process_ 뷰 ()
- 예외 처리 ()
- process_ template_ 응답 ()
미들웨어 실행 순서
대략 같은 장고 요청 라이프 사이클은 그림은 다음과 같은 조건에 의해 영향을받을 수 있습니다
사용자 조작 미들웨어 실행 미들웨어 다른 순서로의 영향을 살펴
시험 아이디어 :
- settings.py에서 다른 미들웨어 가입, 기본 실행 순서 문의
- 순서를 실행합니다 반환 HttpResponse에 개체를 다른 미들웨어 process_request 및 process_response 방법에 미치는 영향은 무엇입니까
- 트리거의 타이밍을 이해하는 다섯 가지 방법
사용자 정의 미들웨어
- (전역 또는 내 응용 프로그램에서) 새 폴더 만들기
- 클래스를 작성하는 것은 MiddlewareMiXin 클래스를 상속
- 내부 (몇 가지 방법에 오)가 필요 쓰는 방법
- 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 미들웨어가 필요하지 않습니다
아약스 보내기
세 가지 (제 후단 표면에서 분리 될 수있다)
첫 페이지 쓰기에서
{% csrf_token %}
, 데이터의에 입력 키 정보를 얻기 위해, 찾기 위해 태그를 사용하여AJAX 데이터 값 여기서, 직접 기록
{{ csrf_token }}
(data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
)공식 문서를 참조하는 것이 좋습니다 페이지에 사용되는 사용자 정의의 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 팁
로 이동하는 코드의 현재 위치를 알고 싶어요, 당신은 그림에있는 아이콘을 클릭하면, 빠른 위치, 당신은 디렉토리 구조를 알릴 수 (아마도 바로 볼 수 있습니다)