02.meiduomall项目day02学习笔记
1,判断用户名重复注册
-
目的: 注册的时候, 需要判断用户名是否已经注册过了
-
分析接口四要素:
- 1, 路径: /usernames/' + this.username + '/count/
- 2, 方式: get
- 3, 请求参数: this.username
- 4, 响应: count, code
-
操作流程:
-
1, 子路由(users/urls.py)
-
url(r'^usernames/(?P<username>\w{5,20})/count/$',views.CheckUsernameView.as_view())
-
-
2, 类视图(users/views.py)
-
#2, 判断用户名是否存在 class CheckUsernameView(View): def get(self,request,username): #1, 根据用户名查询用户数量 count = User.objects.filter(username=username).count() #2, 返回响应 return http.JsonResponse({"count":count,"code":0})
-
-
3, 放开host.js中的注释(host.js)
-
var host = 'http://127.0.0.1:8000'; // var host = 'http://www.meiduo.site:8000';
-
-
2,判断手机号重复注册
-
目的: 注册的时候可以判断, 手机号是否重复了
-
操作流程:
-
1, 子路由(users/urls.py)
-
url(r'^mobiles/(?P<mobile>\d+)/count/$',views.CheckMobileView.as_view()),
-
-
2, 类视图(users/views.py)
-
#3, 判断手机号是否存在 class CheckMobileView(View): def get(self,request,mobile): #1, 根据手机号查询用户数量 count = User.objects.filter(mobile=mobile).count() #2, 返回响应 return http.JsonResponse({"count":count,"code":0})
-
-
3,图片验证码集成
- 目的:知道为什么要集成图片验证码, 以及如何集成capture到项目中
- 操作流程:
- 作用: 保证安全性, 并且在一定的场景下图片验证码还能分流
- 集成到项目中: meiduo_mall/libs/captcha
- 注意点: 需要自己创建libs包
4,verifications应用创建,返回图片
-
目的: 可以创建子应用,编写获取图片验证码视图
-
操作流程:
-
1, 定义图片验证码的redis存储库(dev.py)
-
# redis配置 CACHES = { ... "code": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/2", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } }
-
-
2, 根路由(meiduo_mall/urls.py)
-
url(r'^', include('verifications.urls')),
-
-
3, 子路由(verifications/urls.py)
-
from django.conf.urls import url from . import views urlpatterns = [ url(r'image_codes/(?P<uuid>.+)/',views.ImageCodeView.as_view()) ]
-
-
4, 类视图(verifications/views.py)
-
from django.shortcuts import render from django.views import View from meiduo_mall.libs.captcha.captcha import captcha from django import http from django_redis import get_redis_connection #1,获取图片验证码 class ImageCodeView(View): def get(self,request,uuid): #1, 获取图片验证码, 图片 captcha是外部导入的生成图片验证码功能文件 _,text,image_data = captcha.generate_captcha() # _,text,image_data 三个参数 第一个是空,第二个text,第三个image_data #captcha.generate_captcha() 是captcha.py的启动代码 #2, 存储图片验证码的值到redis中 redis_conn = get_redis_connection("code") redis_conn.set("image_code_%s"%uuid,text,60) #60s为过期时间 #3,返回响应 return http.HttpResponse(image_data,content_type="image/png")
-
5, 前端的图片标签,添加点击事件(register.html)
-
-
<img :src="image_code_url" alt="图形验证码" class="pic_code" @click="generate_image_code">
-
6, 存储图片验证码的值到redis中,需要启动redis,本机已安装,启动文件目录E:\Redis\redis-cli.exe 双击运行即可
-
基本命令 select 2 //2 为存储的库 当前信息存储的是哪个库就切换到哪个库 keys * //查看所有存储的信息
-
-
6,短信验证码分析,实现
-
目的: 可以编写短信验证码后端逻辑
-
操作流程:
-
1, 子路由(verifications/urls.py)
-
url(r'sms_codes/(?P<mobile>\d+)/',views.SMSCodeView.as_view()),
-
-
2, 类视图(verifications/views.py)
-
#2,获取短信验证码 class SMSCodeView(View): def get(self,request,mobile): #1,获取参数 image_code = request.GET.get("image_code") image_code_id = request.GET.get("image_code_id") #2,校验参数 #2,1 为空检验 if not all([image_code,image_code_id]): return http.JsonResponse({"code":4001,"errmsg":"参数不全"}) #2,1 手机号格式 if not re.match(r'^1[3-9]\d{9}$',mobile): return http.JsonResponse({"code": 4001,"errmsg":"手机号格式有误"}) #2,2 图片验证码正确性 redis_conn = get_redis_connection("code") redis_image_code = redis_conn.get("image_code_%s"%image_code_id) if image_code != redis_image_code.decode(): return http.JsonResponse({"code": 4001, "errmsg": "图片验证码错误"}) #3,发送短信,数据入库 sms_code = "%06d"%random.randint(0,999999) print("sms_code = %s"%sms_code) #4,返回响应 return http.JsonResponse({"code":0})
-
-
7,云通讯
- 目的: 可以集成云通讯发送短信
- 使用流程:
- 1, 注册账号,实名认证
- 2, 下载包
- 3, 导入项目中(libs)
- 4, 测试发送
- 需要将自己的应用信息填写到sms.py中
- _accountSid, _accountToken, _appId
- 注意点:
- 发送的手机号, 需要先添加为测试账号
8,短信验证码实现
-
目的: 可以将短信发送的过程集成到项目中
-
操作流程:
-
1, 类视图(verifications/views.py)
-
#2,获取短信验证码 class SMSCodeView(View): def get(self,request,mobile): .... #3,发送短信,数据入库 sms_code = "%06d"%random.randint(0,999999) print("sms_code = %s"%sms_code) result = CCP().send_template_sms(mobile, [sms_code, 5], 1) #3,1 判断是否发送成功 if result == -1: return http.JsonResponse({"code": 4001, "errmsg": "短信发送失败"}) # 3,2 保存短信验证码到redis,方便之后判断短信的正确性 redis_conn.set("sms_code_%s"%mobile,sms_code,300) #4,返回响应 ...
-
-
9,短信验证码校验
-
目的: 可以在注册接口中判断短信验证码的正确性, 并且可以对密码加密
-
操作流程:
-
1, 类视图(users/views.py)
-
class RegisterView(View): def get(self,request): return render(request,'register.html') def post(self,request): ... #2,5 短信验证码正确 redis_conn = get_redis_connection("code") redis_sms_code = redis_conn.get("sms_code_%s"%phone) if msg_code != redis_sms_code.decode(): return http.HttpResponseForbidden("短信验证码填写错误") #2,6 协议需要同意 ... #3, 数据入库 # user = User.objects.create(username=user_name,password=pwd,mobile=phone) # 可以对密码加密 user = User.objects.create_user(username=user_name,password=pwd,mobile=phone) #4, 返回响应 return redirect('/')
-
-
10,短信验证码频繁
-
目的: 可以设置标记, 解决短信频繁发送的问题
-
操作流程:
-
1, 类视图(users/views.py)
-
#2,获取短信验证码 class SMSCodeView(View): def get(self,request,mobile): #1,获取参数 ... #1,1 判断标记是否过期 redis_conn = get_redis_connection("code") send_flag = redis_conn.get("send_flag_%s"%mobile) if send_flag: return http.JsonResponse({"code": 4001, "errmsg": "短信频繁发送"},status=400) ... #3,1 设置标记,防止1分钟之内, 短信多次发送 redis_conn.set("send_flag_%s"%mobile,1,60)
-
-
11,pipeline操作redis
-
目的: 可以通过pipeline(管道)操作redis
-
操作流程:
-
1, 进入到命令调试窗口
- python manager.py shell
-
2, 测试pipeline
-
In [1]: from django_redis import get_redis_connection In [2]: redis_conn = get_redis_connection("default") In [3]: redis_conn.set("name","banzhang") Out[3]: True In [4]: redis_conn.set("age",13) Out[4]: True In [5]: #1, 设置管道 In [6]: pipeline = redis_conn.pipeline() In [7]: pipeline.set("name","banzhang") Out[7]: StrictPipeline<ConnectionPool<Connection<host=127.0.0.1,port=6379,db=1>>> In [8]: pipeline.set("age",13) Out[8]: StrictPipeline<ConnectionPool<Connection<host=127.0.0.1,port=6379,db=1>>> In [9]: #2, 提交管道 In [10]: pipeline.execute() Out[10]: [True, True] In [11]:
-
-
12,celery介绍
- 目的: 知道celery的作用和组成即可
- 作用: 处理耗时任务, 比如: 发短信,发邮件, 发视频, 上传图片等等
- 组成:
13,celery测试
-
目的: 可以参考celery官方文档, 测试celery的运行
-
操作流程:
-
1, 创建celery_tasks包, 编写celery.py模块(celery_tasks/celery.py)
-
from __future__ import absolute_import, unicode_literals import os from celery import Celery #1, 加载项目环境 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "meiduo_mall.settings.dev") #2, 创建celery对象 app = Celery('meiduo_mall') #3, 加载配置 app.config_from_object('celery_tasks.config', namespace='CELERY') #4, 自动注册任务 app.autodiscover_tasks() #5, 手动添加任务 @app.task(bind=True) def debug_task(self): print("debug_task....") # 启动celery: celery -A proj worker -l info # 发送任务: 任务名称.delay(参数)
-
-
2, 创建配置文件config.py
-
#1, 任务队列 broker_url = 'redis://127.0.0.1:6379/14' #2, 结果队列 result_backend = 'redis://127.0.0.1:6379/15'
-
-
3, 启动, 发送任务
-
终端启动celery: celery -A celery_tasks.celery worker -l info
-
注意:celery不支持在windows下运行任务,需要借助eventlet来完成。先安装 pip install eventlet
-
终端启动celery -A celery_tasks.celery worker -l info -P eventlet -c 10
-
参考文档https://www.cnblogs.com/qumogu/p/13284173.html
-
发送任务: 任务名称.delay(参数)
-
需要先进入到python manage.py shell中
-
(venv) E:\python工程\meiduo_mall\day01\meiduo\meiduomall>python manage.py shell Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from celery_tasks.celery import debug_task >>> debug_task.delay() <AsyncResult: 8fac965e-ffb0-4a75-8907-068bc5bdda7c>
-
-
-
14, 使用包的形式封装test任务
-
目的: 可以创建包, 并注册添加到celery并测试使用
-
操作流程:
-
1, 定义test包,创建tasks.py文件(celery_tasks/test/tasks.py)
-
from celery_tasks.celery import app @app.task(bind=True) def sum(self,num1,num2): return num1 + num2
-
-
2, 添加到celery(celery_tasks/celery.py)
-
app.autodiscover_tasks(['celery_tasks.test'])
-
-
3, 测试使用
-
启动: celery -A celery_tasks.celery worker -l info -P eventlet -c 10
-
发送任务:
-
In [1]: from celery_tasks.test.tasks import sum In [2]: result = sum.delay(10,20) In [3]: result.get() Out[3]: 30
-
-
-
15,celery短信发送
-
目的: 操作流程:(失败,在send_message中不调用发送短信的代码)
-
1, 创建短信发送任务包(celery_tasks/sms/tasks.py)
-
from celery_tasks.celery import app from meiduo_mall.libs.yuntongxun.sms import CCP @app.task(bind=True) def send_message(self,mobile,sms_code): import time time.sleep(10) result = CCP().send_template_sms(mobile, [sms_code, 5], 1)
-
-
2, 类视图(verifications/views.py)
-
class SMSCodeView(View): def get(self,request,mobile): ... if not redis_image_code: return http.JsonResponse({"code": 4001, "errmsg": "图片验证码已过期"}) ... #使用celery发送短信 from celery_tasks.sms.tasks import send_message send_message.delay(mobile,sms_code) ...
-
-
16,发送短信重试
-
目的: 可以通过retry方法重试发送短信
-
操作流程:
-
1, sms包的任务更改(celery_tasks/sms/tasks.py)
-
from celery_tasks.celery import app from meiduo_mall.libs.yuntongxun.sms import CCP @app.task(bind=True) def send_message(self,mobile,sms_code): #测试耗时 # import time # time.sleep(10) #1, 发送短信 try: result = CCP().send_template_sms(mobile, [sms_code, 5], 1) except Exception as e: result = -1 #2,判断是否发送成功 if result == -1: #重试, exc: 发送短信失败报的异常, countdown: 间隔几秒重试, max_retries:重试的次数 self.retry(exc=Exception("发送短信失败"),countdown=5,max_retries=3)
-
-
17,用户登陆分析
- 目的: 理解登录流程,和接口四要素
- 接口四要素分析:
- 1,请求地址: /login
- 2, 请求方式: post
- 3, 请求参数: username, pwd, remembered
- 4, 返回响应: 重定向首页
18,登陆实现
-
目的: 可以使用authentication方法实现用户, 认证登录
-
操作流程:
-
1, 子路由(users/urls.py)
-
url(r'^login/$',views.LoginView.as_view()),
-
-
2, 类视图(users/views.py)
-
#4, 登录视图 class LoginView(View): def get(self,request): return render(request,'login.html') def post(self,request): #1,获取参数 username = request.POST.get("username") pwd = request.POST.get("pwd") remembered = request.POST.get("remembered") #2,校验参数 #2,1 为空校验 if not all([username,pwd]): return http.HttpResponseForbidden("参数不全") #2,2 用户名格式 if not re.match(r'^[a-zA-Z0-9_-]{5,20}$',username): return http.HttpResponseForbidden("用户名格式不对") #2,3 密码格式校验 if not re.match(r'^[0-9A-Za-z]{8,20}$',pwd): return http.HttpResponseForbidden("密码格式不对") #2,4 账号密码正确性校验, 如果认证成功返回用户对象, 不成功返回None user = authenticate(request, username=username, password=pwd) if not user: return http.HttpResponseForbidden("账号或者密码不正确") #3,数据入库(状态保持) #4,返回响应 return redirect("/")
-
-
19,登陆状态保持实现
-
目的: 可以通过系统方法login, 实现状态保持
-
操作流程:
-
1, 类视图(users/views.py)
-
class LoginView(View): def get(..) ... def post(..) ... #3,数据入库(状态保持) login(request, user) # 就是将用户的信息存储在session if remembered == "on": #如果用户在前端选择记住密码 request.session.set_expiry(3600*24*2) #保存两天 else: request.session.set_expiry(0) #一次浏览器会话结束 ...
-
-
20,多账号登陆
-
目的: 可以重写系统类的方法, 实现多账号登录(即支持用户名登录也支持手机号登录)
-
操作流程:
-
1, 自定义类,重写authenticate方法(meiduo_mall/utils/my_authenticate.py)
-
from django.contrib.auth.backends import ModelBackend import re from users.models import User #1, 重写系统认证方法 class MyModelBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): #1, 根据username查询用户 try: if re.match(r'^1[3-9]\d{9}$',username): user = User.objects.get(mobile=username) else: user = User.objects.get(username=username) except Exception as e: return None #2, 校验密码 if user.check_password(password): return user else: return None
-
-
2, 设置自定义认证类(dev.py)
-
# 设置自定义认证方法 AUTHENTICATION_BACKENDS = ['meiduo_mall.utils.my_authenticate.MyModelBackend']
-
-
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?