【Django开发】0到1美多商城项目md教程第8篇:用户基本信息,1. 用户模型补充email_active字段【附代码文档】
美多商城完整教程(附代码资料)主要内容讲述:欢迎来到美多商城!,项目准备。展示用户注册页面,创建用户模块子应用。用户注册业务实现,用户注册前端逻辑。图形验证码,图形验证码接口设计和定义。短信验证码,避免频繁发送短信验证码。账号登录,用户名登录。登录,登录开发文档。用户基本信息,查询并渲染用户基本信息。收货地址,省市区三级联动。收货地址,展示地址前后端逻辑。商品数据库表设计,SPU和SKU。准备商品数据,容器化方案Docker。首页广告,展示首页商品频道分类。商品列表页,列表页面包屑导航。商品搜索,Haystack扩展建立索引。商品详情页,统计分类商品访问量。购物车管理,添加购物车。购物车管理,删除购物车。订单,结算订单。提交订单,使用乐观锁并发下单。对接系统,订单支付功能。页面静态化,首页广告页面静态化。MySQL读写分离,MySQL主从同步。
全套笔记资料代码移步: 前往gitee仓库查看
感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~
全套教程部分目录:
部分文件图片:
用户基本信息
查询并渲染用户基本信息
1. 用户模型补充email_active字段
- 由于在渲染用户基本信息时,需要渲染用户邮箱验证的状态,所以需要给用户模型补充email_active字段
- 补充完字段后,需要进行迁移。
$ python manage.py makemigrations
$ python manage.py migrate
class User(AbstractUser):
"""自定义用户模型类"""
mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')
email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')
class Meta:
db_table = 'tb_users'
verbose_name = '用户'
verbose_name_plural = verbose_name
def __str__(self):
return self.username
2. 查询用户基本信息
class UserInfoView(LoginRequiredMixin, View):
"""用户中心"""
def get(self, request):
"""提供个人信息界面"""
context = {
'username': request.user.username,
'mobile': request.user.mobile,
'email': request.user.email,
'email_active': request.user.email_active
}
return render(request, 'user_center_info.html', context=context)
3. 渲染用户基本信息
1.将后端模板数据传递到Vue.js
-
为了方便实现用户添加邮箱时的界面局部刷新
-
我们将后端提供的用户数据传入到
user_center_info.js
中
<script type="text/javascript">
let username = "{{ username }}";
let mobile = "{{ mobile }}";
let email = "{{ email }}";
let email_active = "{{ email_active }}";
</script>
<script type="text/javascript" src="{{ static('js/common.js') }}"></script>
<script type="text/javascript" src="{{ static('js/user_center_info.js') }}"></script>
data: {
username: username,
mobile: mobile,
email: email,
email_active: email_active,
},
2.Vue渲染用户基本信息:
user_center_info.html
<div class="info_con clearfix" v-cloak>
<h3 class="common_title2">基本信息</h3>
<ul class="user_info_list">
<li><span>用户名:</span>[[ username ]]</li>
<li><span>联系方式:</span>[[ mobile ]]</li>
<li>
<span>Email:</span>
<div v-if="set_email">
<input v-model="email" @blur="check_email" type="email" name="email" class="email">
<input @click="save_email" type="button" name="" value="保 存">
<input @click="cancel_email" type="reset" name="" value="取 消">
<div v-show="error_email" class="error_email_tip">邮箱格式错误</div>
</div>
<div v-else>
<input v-model="email" type="email" name="email" class="email" readonly>
<div v-if="email_active">
已验证
</div>
<div v-else>
待验证<input @click="save_email" :disabled="send_email_btn_disabled" type="button" :value="send_email_tip">
</div>
</div>
</li>
</ul>
</div>
添加和验证邮箱
添加邮箱后端逻辑
1. 添加邮箱接口设计和定义
1.请求方式
选项 | 方案 |
---|---|
请求方法 | PUT |
请求地址 | /emails/ |
> | |
2.请求参数 |
参数名 | 类型 | 是否必传 | 说明 |
---|---|---|---|
string | 是 | 邮箱 | |
> | |||
3.响应结果:JSON |
字段 | 说明 |
---|---|
code | 状态码 |
errmsg | 错误信息 |
2. 添加邮箱后端逻辑实现
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': '添加邮箱成功'})
3. 判断用户是否登录并返回JSON
重要提示:
- 只有用户登录时才能让其绑定邮箱。
-
此时前后端交互的数据类型是JSON,所以需要判断用户是否登录并返回JSON给用户。
方案一:
-
使用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
方案二:
- 自定义返回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
Django发送邮件的配置
1. Django发送邮件流程分析
send_mall()
方法介绍
-
位置:
-
在
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字符串
2. 准备发邮件服务器
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>' # 发件人抬头
发送邮箱验证邮件
重要提示:
- 发送邮箱验证邮件是耗时的操作,不能阻塞美多商城的响应,所以需要异步发送邮件。
- 我们继续使用Celery实现异步任务。
1. 定义和调用发送邮件异步任务
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.py
- 在发送邮件的异步任务中,我们用到了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.调用发送邮件异步任务 ```python
赋值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
- 点赞
- 收藏
- 关注作者
评论(0)