【Django开发】0到1开发美多商城项目第3篇:用户注册业务实现(附代码,已分享)
本系列文章md笔记(已分享)主要讨论django商城项目相关知识。项目利用Django框架开发一套前后端不分离的商城项目(4.0版本)含代码和文档。功能包括前后端不分离,方便SEO。采用Django + Jinja2模板引擎 + Vue.js实现前后端逻辑,Nginx服务器(反向代理)Nginx服务器(静态首页、商品详情页、uwsgi服务器(美多商场业务场景),后端服务:MySQL、Redis、Celery、RabbitMQ、Docker、FastDFS、Elasticsearch、Crontab,外部接口:容联云、QQ互联、支付宝。
全套笔记和代码自取在个人博客: https://www.666mao.com/sku?skuId=2
感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~
共 11 章,132 子模块
用户注册业务实现
用户注册前端逻辑
为了学会使用Vue.js的双向绑定实现用户的交互和页面局部刷新效果。
1. 用户注册页面绑定Vue数据
1.准备div盒子标签
<div id="app"><body>......</body>
</div>
2.register.html
- 绑定内容:变量、事件、错误提示等
<form method="post" class="register_form" @submit="on_submit" v-cloak>{{ csrf_input }}<ul><li><label>用户名:</label><input type="text" v-model="username" @blur="check_username" name="username" id="user_name"><span class="error_tip" v-show="error_name">[[ error_name_message ]]</span></li><li><label>密码:</label><input type="password" v-model="password" @blur="check_password" name="password" id="pwd"><span class="error_tip" v-show="error_password">请输入8-20位的密码</span></li><li><label>确认密码:</label><input type="password" v-model="password2" @blur="check_password2" name="password2" id="cpwd"><span class="error_tip" v-show="error_password2">两次输入的密码不一致</span></li><li><label>手机号:</label><input type="text" v-model="mobile" @blur="check_mobile" name="mobile" id="phone"><span class="error_tip" v-show="error_mobile">[[ error_mobile_message ]]</span></li><li><label>图形验证码:</label><input type="text" name="image_code" id="pic_code" class="msg_input"><img src="{{ static('images/pic_code.jpg') }}" alt="图形验证码" class="pic_code"><span class="error_tip">请填写图形验证码</span></li><li><label>短信验证码:</label><input type="text" name="sms_code" id="msg_code" class="msg_input"><a href="javascript:;" class="get_msg_code">获取短信验证码</a><span class="error_tip">请填写短信验证码</span></li><li class="agreement"><input type="checkbox" v-model="allow" @change="check_allow" name="allow" id="allow"><label>同意”美多商城用户使用协议“</label><span class="error_tip2" v-show="error_allow">请勾选用户协议</span></li><li class="reg_sub"><input type="submit" value="注 册"></li></ul>
</form>
2. 用户注册JS文件实现用户交互
1.导入Vue.js库和ajax请求的库
<script type="text/javascript" src="{{ static('js/vue-2.5.16.js') }}"></script>
<script type="text/javascript" src="{{ static('js/axios-0.18.0.min.js') }}"></script>
2.准备register.js文件
<script type="text/javascript" src="{{ static('js/register.js') }}"></script>
绑定内容:变量、事件、错误提示等
let vm = new Vue({el: '#app',// 修改Vue读取变量的语法delimiters: ['[[', ']]'],data: {username: '',password: '',password2: '',mobile: '',allow: '',error_name: false,error_password: false,error_password2: false,error_mobile: false,error_allow: false,error_name_message: '',error_mobile_message: '',},methods: {// 校验用户名check_username(){},// 校验密码check_password(){},// 校验确认密码check_password2(){},// 校验手机号check_mobile(){},// 校验是否勾选协议check_allow(){},// 监听表单提交事件on_submit(){},}
});
3.用户交互事件实现
methods: {// 校验用户名check_username(){let re = /^[a-zA-Z0-9_-]{5,20}$/;if (re.test(this.username)) {this.error_name = false;} else {this.error_name_message = '请输入5-20个字符的用户名';this.error_name = true;}},// 校验密码check_password(){let re = /^[0-9A-Za-z]{8,20}$/;if (re.test(this.password)) {this.error_password = false;} else {this.error_password = true;}},// 校验确认密码check_password2(){if(this.password != this.password2) {this.error_password2 = true;} else {this.error_password2 = false;}},// 校验手机号check_mobile(){let re = /^1[3-9]\d{9}$/;if(re.test(this.mobile)) {this.error_mobile = false;} else {this.error_mobile_message = '您输入的手机号格式不正确';this.error_mobile = true;}},// 校验是否勾选协议check_allow(){if(!this.allow) {this.error_allow = true;} else {this.error_allow = false;}},// 监听表单提交事件on_submit(){this.check_username();this.check_password();this.check_password2();this.check_mobile();this.check_allow();if(this.error_name == true || this.error_password == true || this.error_password2 == true|| this.error_mobile == true || this.error_allow == true) {// 禁用表单的提交window.event.returnValue = false;}},
}
4. 知识要点
-
Vue绑定页面的套路
- 导入Vue.js库和ajax请求的库
- 准备div盒子标签
- 准备js文件
- html页面绑定变量、事件等
- js文件定义变量、事件等
-
错误提示
- 如果错误提示信息是固定的,可以把错误提示信息写死,再通过v-show控制是否展示
- 如果错误提示信息不是固定的,可以使用绑定的变量动态的展示错误提示信息,再通过v-show控制是否展示
-
修改Vue变量的读取语法,避免和Django模板语法冲突
delimiters: ['[[', ']]']
-
后续的页面中如果有类似的交互和刷新效果,也可按照此套路实现
用户注册后端逻辑
1. 接收参数
提示:用户注册数据是从注册表单发送过来的,所以使用**request.POST
**来提取。
username = request.POST.get('username')
password = request.POST.get('password')
password2 = request.POST.get('password2')
mobile = request.POST.get('mobile')
allow = request.POST.get('allow')
2. 校验参数
前端校验过的后端也要校验,后端的校验和前端的校验是一致的
# 判断参数是否齐全# 判断用户名是否是5-20个字符# 判断密码是否是8-20个数字# 判断两次密码是否一致# 判断手机号是否合法# 判断是否勾选用户协议
# 判断参数是否齐全if not all([username, password, password2, mobile, allow]):return http.HttpResponseForbidden('缺少必传参数')# 判断用户名是否是5-20个字符if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):return http.HttpResponseForbidden('请输入5-20个字符的用户名')# 判断密码是否是8-20个数字if not re.match(r'^[0-9A-Za-z]{8,20}$', password):return http.HttpResponseForbidden('请输入8-20位的密码')# 判断两次密码是否一致if password != password2:return http.HttpResponseForbidden('两次输入的密码不一致')# 判断手机号是否合法if not re.match(r'^1[3-9]\d{9}$', mobile):return http.HttpResponseForbidden('请输入正确的手机号码')# 判断是否勾选用户协议if allow != 'on':return http.HttpResponseForbidden('请勾选用户协议')
提示:这里校验的参数,前端已经校验过,如果此时参数还是出错,说明该请求是非正常渠道发送的,所以直接禁止本次请求。
3. 保存注册数据
- 这里使用Django认证系统用户模型类提供的 create_user() 方法创建新的用户。
- 这里 create_user() 方法中封装了 set_password() 方法加密密码。
# 保存注册数据try:User.objects.create_user(username=username, password=password, mobile=mobile)
except DatabaseError:return render(request, 'register.html', {'register_errmsg': '注册失败'})# 响应注册结果return http.HttpResponse('注册成功,重定向到首页')
如果注册失败,我们需要在页面上渲染出注册失败的提示信息。
{% if register_errmsg %}<span class="error_tip2">{{ register_errmsg }}</span>
{% endif %}
4. 响应注册结果
- 重要提示:注册成功,重定向到首页
1.创建首页广告应用:contents
$ cd ~/projects/meiduo_project/meiduo_mall/meiduo_mall/apps
$ python ../../manage.py startapp contents
2.定义首页广告视图:IndexView
class IndexView(View):"""首页广告"""def get(self, request):"""提供首页广告界面"""return render(request, 'index.html')
3.配置首页广告路由:绑定命名空间
# contentsurl(r'^', include('contents.urls', namespace='contents')),
# 首页广告url(r'^$', views.IndexView.as_view(), name='index'),
4.测试首页广告是否可以正常访问
http://127.0.0.1:8000/
5.响应注册结果:重定向到首页
# 响应注册结果return redirect(reverse('contents:index'))
5. 知识要点
-
后端逻辑编写套路:
- 业务逻辑分析
- 接口设计和定义
- 接收和校验参数
- 实现主体业务逻辑
- 响应结果
-
注册业务逻辑核心思想:
- 保存用户注册数据
状态保持
说明:
- 如果需求是注册成功后即表示用户登入成功,那么此时可以在注册成功后实现状态保持
- 如果需求是注册成功后不表示用户登入成功,那么此时不用在注册成功后实现状态保持
美多商城的需求是:注册成功后即表示用户登入成功
1. login()方法介绍
-
用户登入本质:
- 状态保持
- 将通过认证的用户的唯一标识信息(比如:用户ID)写入到当前浏览器的 cookie 和服务端的 session 中。
-
login()方法:
- Django用户认证系统提供了
login()
方法。 - 封装了写入session的操作,帮助我们快速登入一个用户,并实现状态保持。
- Django用户认证系统提供了
-
login()位置:
django.contrib.auth.__init__.py
文件中。
login(request, user, backend=None)
4. 状态保持 session 数据存储的位置:**Redis数据库的1号库**
```python
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"
2. login()方法登入用户
# 保存注册数据try:user = User.objects.create_user(username=username, password=password, mobile=mobile)
except DatabaseError:return render(request, 'register.html', {'register_errmsg': '注册失败'})# 登入用户,实现状态保持login(request, user)# 响应注册结果return redirect(reverse('contents:index'))
3. 查看状态保持结果
4. 知识要点
- 登入用户,并实现状态保持的方式:
login(request, user, backend=None)
用户名重复注册
1. 用户名重复注册逻辑分析
2. 用户名重复注册接口设计和定义
1.请求方式
选项 | 方案 |
---|---|
请求方法 | GET |
请求地址 | /usernames/(?P[a-zA-Z0-9_-]{5,20})/count/ |
2.请求参数:路径参数
参数名 | 类型 | 是否必传 | 说明 |
---|---|---|---|
username | string | 是 | 用户名 |
3.响应结果:JSON
响应结果 | 响应内容 |
---|---|
code | 状态码 |
errmsg | 错误信息 |
count | 记录该用户名的个数 |
3. 用户名重复注册后端逻辑
class UsernameCountView(View):"""判断用户名是否重复注册"""def get(self, request, username):""":param request: 请求对象:param username: 用户名:return: JSON"""count = User.objects.filter(username=username).count()return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'count': count})
4. 用户名重复注册前端逻辑
if (this.error_name == false) {let url = '/usernames/' + this.username + '/count/';axios.get(url,{responseType: 'json'}).then(response => {if (response.data.count == 1) {this.error_name_message = '用户名已存在';this.error_name = true;} else {this.error_name = false;}}).catch(error => {console.log(error.response);})
}
5. 知识要点
-
判断用户名重复注册的核心思想:
- 使用用户名查询该用户名对应的记录是否存在,如果存在,表示重复注册了,反之,没有重复注册。
-
axios发送异步请求套路:
- 处理用户交互
- 收集请求参数
- 准备请求地址
- 发送异步请求
- 得到服务器响应
- 控制界面展示效果
手机号重复注册
1. 手机号重复注册逻辑分析
2. 手机号重复注册接口设计和定义
1.请求方式
选项 | 方案 |
---|---|
请求方法 | GET |
请求地址 | /mobiles/(?P1[3-9]\d{9})/count/ |
2.请求参数:路径参数
参数名 | 类型 | 是否必传 | 说明 |
---|---|---|---|
mobile | string | 是 | 手机号 |
3.响应结果:JSON
响应结果 | 响应内容 |
---|---|
code | 状态码 |
errmsg | 错误信息 |
count | 记录该用户名的个数 |
3. 手机号重复注册后端逻辑
class MobileCountView(View):"""判断手机号是否重复注册"""def get(self, request, mobile):""":param request: 请求对象:param mobile: 手机号:return: JSON"""count = User.objects.filter(mobile=mobile).count()return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'count': count})
4. 手机号重复注册前端逻辑
if (this.error_mobile == false) {let url = '/mobiles/'+ this.mobile + '/count/';axios.get(url, {responseType: 'json'}).then(response => {if (response.data.count == 1) {this.error_mobile_message = '手机号已存在';this.error_mobile = true;} else {this.error_mobile = false;}}).catch(error => {console.log(error.response);})
}
验证码
图形验证码
图形验证码逻辑分析
需要新建应用verifications
知识要点
- 将图形验证码的文字信息保存到Redis数据库,为短信验证码做准备。
- UUID 用于唯一区分该图形验证码属于哪个用户,也可使用其他唯一标识信息来实现。
未完待续, 同学们请等待下一期
全套笔记和代码自取在个人博客: https://www.666mao.com/sku?skuId=2
感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~
r_mobile == false) {
let url = ‘/mobiles/’+ this.mobile + ‘/count/’;
axios.get(url, {
responseType: ‘json’
})
.then(response => {
if (response.data.count == 1) {
this.error_mobile_message = ‘手机号已存在’;
this.error_mobile = true;
} else {
this.error_mobile = false;
}
})
.catch(error => {
console.log(error.response);
})
}
# 验证码# 图形验证码# 图形验证码逻辑分析[外链图片转存中...(img-gTfk28oA-1706789118562)]
>
需要新建应用`verifications`### 知识要点1. 将图形验证码的文字信息保存到Redis数据库,为短信验证码做准备。
2. UUID 用于唯一区分该图形验证码属于哪个用户,也可使用其他唯一标识信息来实现。# 未完待续, 同学们请等待下一期# 全套笔记和代码自取在个人博客: [https://www.666mao.com/sku?skuId=2](https://www.666mao.com/sku?skuId=2)# 感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~
相关文章:

【Django开发】0到1开发美多商城项目第3篇:用户注册业务实现(附代码,已分享)
本系列文章md笔记(已分享)主要讨论django商城项目相关知识。项目利用Django框架开发一套前后端不分离的商城项目(4.0版本)含代码和文档。功能包括前后端不分离,方便SEO。采用Django Jinja2模板引擎 Vue.js实现前后端…...

免费的ppt网站分享
前言 相信大学生们深有体会,对于学校而言,好像是任何活动都需要我们做ppt,当你拿着自己辛苦做的ppt去展示现场的时候,你看到别人的ppt比你的还好,此时心情就是毙,当你知道人家不过是仅仅的1个小时不到就完成…...

基于Transformer结构的扩散模型综述
🎀个人主页: https://zhangxiaoshu.blog.csdn.net 📢欢迎大家:关注🔍点赞👍评论📝收藏⭐️,如有错误敬请指正! 💕未来很长,值得我们全力奔赴更美好的生活&…...

POI操作word表格,添加单元格,单元格对齐方法(不必合并单元格)
添加单元格,直接对row进行create新的cell,则会导致新创建的单元格与前面的单元格不对齐的现象。 //表格信息XWPFTable table doc.createTable();table.setWidth("100%");//第一行XWPFTableRow row0table.getRow(0);XWPFTableCell cell00row0.…...

maven代码规范检查(checkstyle、findbugs)
maven代码规范检查 前言一、使用checkstyle插件1. maven-checkstyle-plugin 介绍2. 接入方式3. 如何排除某个类、包下面的文件不进行检查使用suppressionsLocation 4. 如何关闭 二、使用findbugs插件1.findbugs-maven-plugin介绍2. 接入方式3. 如何排除某个类、包下面的文件不进…...
妙用Java反射,让代码更加优雅
最近在改公司项目bug,需要修改别人的代码。在读别人的源码时感觉到反射真的是能够极大的提高代码的优雅性,在某些特定场景能极大的简化代码的编写。因此写了这篇文章用以记录分享。 我们先还原一下场景,在做数据展示的时候,需要处…...

实习日志10
1.用户信息 1.1.在用户管理中编辑用户信息 1.2.绑定公司id 1.3.显示在页面 2.修改识别逻辑 2.1.分析 先识别,再判断,清空键把识别结果清空 2.2.写码 修改了发票识别逻辑,略... 3.接高拍仪 3.1.js引入报错 分析: 遇到的错误…...
配置alias(设置别名@)
Vite配置alias需要两步进行(TS项目) 1、修改vite.config.ts(让程序支持)2、修改tsconfig.json(让编辑器支持)修改vite.config.ts import { defineConfig } from vite import path from path function…...

【动态规划】【数学】1388. 3n 块披萨
作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1388 3n 块披萨 给你一个披萨,它由 3n 块不同大小的部分组成,现在你和你的朋友们需要按照如下规则来分披萨: 你挑选 任…...

CS144--Chapter0--wsl2+docker环境搭建
我的笔记本配置 荣耀magicbook16,容量是500G,芯片是R7-5800 由于笔记本容量较小,因此考虑这个方案,对于台式机用户,建议可以直接用虚拟机或者双系统。 前言 斯坦福官网给出的方法是用他们的镜像(基于Ubu…...

MGRE实验报告二
实验要求: 实验预览图: 实验分析: 1、对R1-R5配置IP地址,同时R1-R5每个路由器各有一个环回 2.1、对R1、R3、R4路由器开启虚拟接口1,分别配置隧道IP、接口封装协议,接口类型、定义封装源、开启伪广播功能&…...

算法设计与分析实验:最短路径算法
一、网络延迟时间 力扣第743题 本题采用最短路径的思想进行求解 1.1 具体思路 (1)使用邻接表表示有向图:首先,我们可以使用邻接表来表示有向图。邻接表是一种数据结构,用于表示图中顶点的相邻关系。在这个问题中&am…...

共用体与枚举法,链表的学习
结构体注意事项: 1.结构体类型可以定义在main函数里面,但是此时的作用域就被限定在该函数中 2.结构体的的的定义的形式:a.先定义类型,后定义变量-----struct stu s b.定义类型的同时,定义了变量:struct…...

SG2520CAA汽车用晶体振荡器
爱普生SG2520CAA是简单的封装晶体振荡器(SPXO),具有CMOS输出,这款SPXO是汽车和高可靠性应用的理想选择,符合AEC-Q200标准,功耗低,工作电压范围为1.8 V ~ 3.3 V类型,宽工作温度-40℃~…...
使用pip将第三方依赖包下载到本地指定位置
pip download -d save_path packages -d:后面接下载包路径(save_path) packages:安装包名称...

C语言探索:水仙花数的奥秘与计算
摘要: 水仙花数,一种特殊的三位数,其各位数字的立方和等于该数本身。本文将详细介绍水仙花数的定义、性质,以及如何使用C语言来寻找100至999范围内的水仙花数。 目录 一、水仙花数的定义与性质 二、用C语言寻找100至999范围内的…...

2024年人工智能应用与先进制造科学国际学术会议(ICAIAAMS 2024)
2024年人工智能应用与先进制造科学国际学术会议(ICAIAAMS 2024) 2024 International Conference on Artificial Intelligence Applications and Advanced Manufacturing Science (ICAIAAMS 2024) 会议简介: 2024年人工智能应用与先进制造科学国际学术会议ÿ…...

计算机图形学 实验
题目要求 1.1 实验一:图元的生成:直线、圆椭区域填充 你需要完成基本的图元生成算法,包括直线和椭圆。 在区域填充中,要求你对一个封闭图形进行填充。你需要绘制一个封 闭图形(例如多边形),并选…...

React + react-device-detect 实现设备特定的渲染
当构建响应式网页应用时,了解用户正在使用的设备类型(如手机、平板或桌面)可以帮助我们提供更优化的用户体验。本文将介绍如何在 React 项目中使用 react-device-detect 库来检测设备类型,并根据不同的设备显示不同的组件或样式。…...

文献速递:肿瘤分割----基于卷积神经网络的系统,用于前列腺癌[68Ga]Ga-PSMA PET全身图像的全自动分割
文献速递:肿瘤分割----基于卷积神经网络的系统,用于前列腺癌[68Ga]Ga-PSMA PET全身图像的全自动分割 01 文献速递介绍 前列腺特异性膜抗原(PSMA)PET/CT成像近年来在前列腺癌检测领域中获得了显著的重视。PSMA是一种在前列腺上皮…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...