
教程总体简介:美多商城 商业模式介绍 1.B2B--企业对企业 2.C2C--个人对个人 5.O2O--线上到线下 开发流程 说明: 需求分析 1. 用户部分 注册 登录 个人信息 地址管理 修改密码 3. 购物车部分 购物车管理 项目架构 创建工程 1. 在git平台创建工程 2. 添加前端文件 合并 3. 创建Django REST framework工程 4. 修改manage.py 5. 创建数据库 收货地址 省市区地址查询 数据库建表 后端接口设计 前端 使用缓存 安装 使用方法 为省市区视图添加缓存 缓存数据保存位置与有效期的设置 用户地址管理代码 后端 商品部分 数据库表设计 表结构 数据库模型类 FastDFS分布式文件系统 1. 什么是FastDFS 2. 文件上传流程 Docker使用 安装与操作 1. 在Ubuntu中安装Docker 2. 启动与停止 3. Docker镜像操作 5. 将容器保存为镜像 6. 镜像备份与迁移 使用Docker安装FastDFS 1. 获取镜像 2. 运行tracker 3. 运行storage CKEditor富文本编辑器 1. 安装 3. 添加CKEditor设置 5. 为模型类添加字段 6. 修改Bug 添加测试数据 在admin中注册模型类 添加FastDFS保存的测试图片数据 添加对应的数据库测试数据 页面静态化 注意 定时任务 添加应用 设置任务的定时时间 静态化首页的手动脚本 商品详情页 异步任务的触发 脚本工具 用户浏览历史记录 2. 查看 商品搜索 2. 搜索引擎原理 3. Elasticsearch 4. 使用Docker安装Elasticsearch及其扩展 6. 前端 项目准备 配置 1. 修改settings/dev.py 文件中的路径信息 2. INSTALLED_APPS 4. Redis 5. 本地化语言与时区 7. 异常处理 用户模型类 Django用户模型类 创建自定义的用户模型类 购物车数据存储设计 1. Redis保存已登录用户 添加到购物车 2. 后端实现 查询购物车数据 登录合并购物车 修改登录视图 订单结算 订单部分 保存订单 4. 使用乐观锁改写下单逻辑 5. 需要修改MySQL的事务隔离级别 下单成功页面 前端文件 沙箱环境 电脑网站支付流程 接入步骤 配置秘钥 发起支付 保存支付结果 Xadmin 用户权限控制 数据库读写分离 MySQL主从同步 1. 主从同步的定义 3. 配置主从同步的基本步骤 4. 详细配置主从同步的方法 配置Django实现数据库读写分离 2. 创建数据库操作的路由分发类 部署 1. 静态文件 2. 动态接口 图片验证码 3. 设置域名 4. 前端Vue代码: 跨域CORS 使用Celery完成发送短信 判断帐号是否存在 1. 判断用户名是否存在 JWT 什么是JWT 起源 传统的session认证 基于token的鉴权机制 JWT长什么样? JWT的构成 header playload signature 如何应用 urllib使用说明 绑定用户身份接口 用户中心个人信息 邮件与验证 使用Django发送邮件 保存邮箱并发送验证邮件 验证邮箱链接
感兴趣的小伙伴可以自取哦~
全套教程部分目录:


部分文件图片:

用户部分
图片验证码
1. 后端接口设计:
访问方式: GET /image_codes/(?P<image_code_id>[\w-]+)/
请求参数: 路径参数
参数 |
类型 |
是否必须 |
说明 |
image_code_id |
uuid字符串 |
是 |
图片验证码编号 |
返回数据:
验证码图片
视图原型
| # url('^image_codes/(?P<image_code_id>[\w-]+)/$', views.ImageCodeView.as_view()),
class ImageCodeView(APIView):
"""
图片验证码
"""
pass
|
2. 具体视图实现
在verifications/views.py中实现视图
| class ImageCodeView(APIView):
"""
图片验证码
"""
def get(self, request, image_code_id):
"""
获取图片验证码
"""
# 生成验证码图片
text, image = captcha.generate_captcha()
redis_conn = get_redis_connection("verify_codes")
redis_conn.setex("img_%s" % image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
# 固定返回验证码图片数据,不需要REST framework框架的Response帮助我们决定返回响应数据的格式
# 所以此处直接使用Django原生的HttpResponse即可
return HttpResponse(image, content_type="images/jpg")
|
说明:
django-redis提供了get_redis_connection的方法,通过调用get_redis_connection方法传递redis的配置名称可获取到redis的连接对象,通过redis连接对象可以执行redis命令。
我们需要在配置文件中添加一个新的redis配置,用于存放验证码数据
| CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://10.211.55.5:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
"session": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://10.211.55.5:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
"verify_codes": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://10.211.55.5:6379/2",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
|
3. 设置域名
我们现在为前端和后端分别设置两个不同的域名
位置 |
域名 |
前端 |
www.meiduo.site |
后端 |
api.meiduo.site |
编辑/etc/hosts
文件,可以设置本地域名
在文件中增加两条信息
| 127.0.0.1 api.meiduo.site
127.0.0.1 www.meiduo.site
|
windows系统中若设置本地域名,hosts文件在如下目录:
| C:\Windows\System32\drivers\etc
|
我们在前端front_end_pc/js目录中,创建host.js文件用以为前端保存后端域名
在所有需要访问后端接口的前端页面中都引入host.js,使用host
变量即可指代后端域名。
修改settings配置中的ALLOWED_HOSTS
一旦不再使用127.0.0.1访问Django后端,需要在配置文件中修改ALLOWED_HOSTS,增加可以访问后端的域名
| ALLOWED_HOSTS = ['api.meiduo.site', '127.0.0.1', 'localhost', 'www.meiduo.site']
|
4. 前端Vue代码:
js/register.js
| data: {
...
image_code_id: '', // 图片验证码编号
image_code_url: '', // 验证码图片路径
},
mounted: function() {
this.generate_image_code();
},
methods: {
// 生成uuid
generate_uuid: function(){
var d = new Date().getTime();
if(window.performance && typeof window.performance.now === "function"){
d += performance.now(); //use high-precision timer if available
}
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c =='x' ? r : (r&0x3|0x8)).toString(16);
});
return uuid;
},
// 生成一个图片验证码的编号,并设置页面中图片验证码img标签的src属性
generate_image_code: function(){
// 生成一个编号
// 严格一点的使用uuid保证编号唯一, 不是很严谨的情况下,也可以使用时间戳
this.image_code_id = this.generate_uuid();
// 设置页面中图片验证码img标签的src属性
this.image_code_url = this.host + "/image_codes/" + this.image_code_id + "/";
},
...
}
|
短信验证码
1. 业务处理流程
- 检查图片验证码
- 检查是否在60s内有发送记录
- 生成短信验证码
- 保存短信验证码与发送记录
- 发送短信
2. 后端接口设计:
访问方式: GET /sms_codes/(?P<mobile>1[3-9]\d{9})/?image_code_id=xxx&text=xxx
请求参数: 路径参数与查询字符串参数
参数 |
类型 |
是否必须 |
说明 |
mobile |
str |
是 |
号 |
image_code_id |
uuid字符串 |
是 |
图片验证码编号 |
text |
str |
是 |
用户输入的图片验证码 |
返回数据: JSON
返回值 |
类型 |
是否必传 |
说明 |
message |
str |
否 |
OK,发送成功 |
视图原型:
| # url('^sms_codes/(?P<mobile>1[3-9]\d{9})/$', views.SMSCodeView.as_view()),
class SMSCodeView(GenericAPIView):
"""
短信验证码
传入参数:
mobile, image_code_id, text
"""
pass
|
3. 后端实现
在verifications/serializers.py中定义序列化器,用以校验
| class ImageCodeCheckSerializer(serializers.Serializer):
"""
图片验证码校验序列化器
"""
image_code_id = serializers.UUIDField()
text = serializers.CharField(max_length=4, min_length=4)
def validate(self, attrs):
"""
校验
"""
image_code_id = attrs['image_code_id']
text = attrs['text']
# 查询真实图片验证码
redis_conn = get_redis_connection('verify_codes')
real_image_code_text = redis_conn.get('img_%s' % image_code_id)
if not real_image_code_text:
raise serializers.ValidationError('图片验证码无效')
# 删除图片验证码
try:
redis_conn.delete('img_%s' % image_code_id)
except RedisError as e:
logger.error(e)
# 比较图片验证码
real_image_code_text = real_image_code_text.decode()
if real_image_code_text.lower() != text.lower():
raise serializers.ValidationError('图片验证码错误')
# 判断是否在60s内
mobile = self.context['view'].kwargs['mobile']
send_flag = redis_conn.get("send_flag_%s" % mobile)
if send_flag:
raise serializers.ValidationError('请求次数过于频繁')
return attrs
|
在verifications/views.py中定义实现视图:
| class SMSCodeView(GenericAPIView):
"""
短信验证码
"""
serializer_class = serializers.ImageCodeCheckSerializer
def get(self, request, mobile):
"""
创建短信验证码
"""
# 判断图片验证码, 判断是否在60s内
serializer = self.get_serializer(data=request.query_params)
serializer.is_valid(raise_exception=True)
# 生成短信验证码
sms_code = "%06d" % random.randint(0, 999999)
# 保存短信验证码与发送记录
redis_conn = get_redis_connection('verify_codes')
pl = redis_conn.pipeline()
pl.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
pl.setex("send_flag_%s" % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
pl.execute()
# 发送短信验证码
sms_code_expires = str(constants.SMS_CODE_REDIS_EXPIRES // 60)
ccp = CCP()
ccp.send_template_sms(mobile, [code, expires], SMS_CODE_TEMP_ID)
return Response({"message": "OK"})
|
4. 前端实现
修改register.html
```html
美多商城-注册
<link rel="stylesheet" type="text/css" href="css/reset
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)