1.請求方式
選項 | 方案 |
---|---|
請求方法 | PUT |
請求地址 | /emails/ |
2.請求參數
參數名 | 類型 | 是否必傳 | 說明 |
---|---|---|---|
string | 是 | 郵箱 |
3.響應結果:JSON
字段 | 說明 |
---|---|
code | 狀態碼 |
errmsg | 錯誤信息 |
class EmailView(View): """添加郵箱""" def put(self, request): """實現添加郵箱邏輯""" # 接收參數 json_dict = json.loads(request.body.decode()) email = json_dict.get('email') # 校驗參數 if not email: return http.HttpResponseForbidden('缺乏email參數') if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email): return http.HttpResponseForbidden('參數email有誤') # 賦值email字段 try: request.user.email = email request.user.save() except Exception as e: logger.error(e) return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '添加郵箱失敗'}) # 響應添加郵箱結果 return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加郵箱成功'})
重要提示:
方案一:html
- 使用Django用戶認證系統提供的
is_authenticated()
class EmailView(View): """添加郵箱""" def put(self, request): """實現添加郵箱邏輯""" # 判斷用戶是否登陸並返回JSON if not request.user.is_authenticated(): return http.JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用戶未登陸'}) pass
方案二:python
- 自定義返回JSON的
login_required
裝飾器- 在
meiduo_mall.utils.views.py
中
def login_required_json(view_func): """ 判斷用戶是否登陸的裝飾器,並返回json :param view_func: 被裝飾的視圖函數 :return: json、view_func """ # 恢復view_func的名字和文檔 @wraps(view_func) def wrapper(request, *args, **kwargs): # 若是用戶未登陸,返回json數據 if not request.user.is_authenticated(): return http.JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用戶未登陸'}) else: # 若是用戶登陸,進入到view_func中 return view_func(request, *args, **kwargs) return wrapper class LoginRequiredJSONMixin(object): """驗證用戶是否登錄並返回json的擴展類""" @classmethod def as_view(cls, **initkwargs): view = super().as_view(**initkwargs) return login_required_json(view)
LoginRequiredJSONMixin
的使用
class EmailView(LoginRequiredJSONMixin, View): """添加郵箱""" def put(self, request): """實現添加郵箱邏輯""" # 判斷用戶是否登陸並返回JSON pass
send_mall()
方法介紹django
位置:json
- 在
django.core.mail
模塊提供了send_mail()
來發送郵件。方法參數:後端
send_mail(subject, message, from_email, recipient_list, html_message=None)
subject 郵件標題 message 普通郵件正文,普通字符串 from_email 發件人 recipient_list 收件人列表 html_message 多媒體郵件正文,能夠是html字符串
1.點擊進入《設置》界面
2.點擊進入《客戶端受權密碼》界面
3.開啓《受權碼》,並完成驗證短信
4.填寫《受權碼》
5.完成《受權碼》設置
6.配置郵件服務器
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # 指定郵件後端 EMAIL_HOST = 'smtp.163.com' # 發郵件主機 EMAIL_PORT = 25 # 發郵件端口 EMAIL_HOST_USER = 'hmmeiduo@163.com' # 受權的郵箱 EMAIL_HOST_PASSWORD = 'hmmeiduo123' # 郵箱受權時得到的密碼,非註冊登陸密碼 EMAIL_FROM = '美多商城<hmmeiduo@163.com>' # 發件人擡頭
重要提示:
1.定義發送郵件任務
@celery_app.task(bind=True, name='send_verify_email', retry_backoff=3) def send_verify_email(self, to_email, verify_url): """ 發送驗證郵箱郵件 :param to_email: 收件人郵箱 :param verify_url: 驗證連接 :return: None """ subject = "商城郵箱驗證" html_message = '<p>尊敬的用戶您好!</p>' \ '<p>感謝您使用商城。</p>' \ '<p>您的郵箱爲:%s 。請點擊此連接激活您的郵箱:</p>' \ '<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url) try: send_mail(subject, "", settings.EMAIL_FROM, [to_email], html_message=html_message) except Exception as e: logger.error(e) # 有異常自動重試三次 raise self.retry(exc=e, max_retries=3)
2.註冊發郵件的任務:main.pybash
- 在發送郵件的異步任務中,咱們用到了Django的配置文件。
- 因此咱們須要修改celery的啓動文件main.py。
- 在其中指明celery能夠讀取的Django配置文件。
- 最後記得註冊新添加的email的任務
# celery啓動文件 from celery import Celery # 爲celery使用django配置文件進行設置 import os if not os.getenv('DJANGO_SETTINGS_MODULE'): os.environ['DJANGO_SETTINGS_MODULE'] = 'meiduo_mall.settings.dev' # 建立celery實例 celery_app = Celery('meiduo') # 加載celery配置 celery_app.config_from_object('celery_tasks.config') # 自動註冊celery任務 celery_app.autodiscover_tasks(['celery_tasks.sms', 'celery_tasks.email'])
3.調用發送郵件異步任務
# 賦值email字段 try: request.user.email = email request.user.save() except Exception as e: logger.error(e) return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '添加郵箱失敗'}) # 異步發送驗證郵件 verify_url = '郵件驗證連接' send_verify_email.delay(email, verify_url) # 響應添加郵箱結果 return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加郵箱成功'})
4.啓動Celery
$ celery -A celery_tasks.main worker -l info
1.定義生成郵箱驗證連接方法
def generate_verify_email_url(user): """ 生成郵箱驗證連接 :param user: 當前登陸用戶 :return: verify_url """ serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES) data = {'user_id': user.id, 'email': user.email} token = serializer.dumps(data).decode() verify_url = settings.EMAIL_VERIFY_URL + '?token=' + token return verify_url
2.配置相關參數
# 郵箱驗證連接 EMAIL_VERIFY_URL = 'http://www.shagncheng.site:8000/emails/verification/'
3.使用郵箱驗證連接
verify_url = generate_verify_email_url(request.user) send_verify_email.delay(email, verify_url)
1.請求方式
選項 | 方案 |
---|---|
請求方法 | GET |
請求地址 | /emails/verification/ |
2.請求參數:查詢參數
參數名 | 類型 | 是否必傳 | 說明 |
---|---|---|---|
token | string | 是 | 郵箱激活連接 |
3.響應結果:HTML
字段 | 說明 |
---|---|
郵箱驗證失敗 | 響應錯誤提示 |
郵箱驗證成功 | 重定向到用戶中心 |
def check_verify_email_token(token): """ 驗證token並提取user :param token: 用戶信息簽名後的結果 :return: user, None """ serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES) try: data = serializer.loads(token) except BadData: return None else: user_id = data.get('user_id') email = data.get('email') try: user = User.objects.get(id=user_id, email=email) except User.DoesNotExist: return None else: return user
驗證郵箱的核心:就是將用戶的email_active
字段設置爲True
class VerifyEmailView(View): """驗證郵箱""" def get(self, request): """實現郵箱驗證邏輯""" # 接收參數 token = request.GET.get('token') # 校驗參數:判斷token是否爲空和過時,提取user if not token: return http.HttpResponseBadRequest('缺乏token') user = check_verify_email_token(token) if not user: return http.HttpResponseForbidden('無效的token') # 修改email_active的值爲True try: user.email_active = True user.save() except Exception as e: logger.error(e) return http.HttpResponseServerError('激活郵件失敗') # 返回郵箱驗證結果 return redirect(reverse('users:info'))
關注公衆號:測試老憨,回覆:商城,獲取完成項目代碼