展示用户注册页面

1. 准备用户注册模板文件 

 

 

加载页面静态文件

<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>美多商城-注册</title>
    <link rel="stylesheet" type="text/css" href="{{ static('css/reset.css') }}">
    <link rel="stylesheet" type="text/css" href="{{ static('css/main.css') }}">
</head>

2. 定义用户注册视图

class RegisterView(View):
    """用户注册"""

    def get(self, request):
        """
        提供注册界面
        :param request: 请求对象
        :return: 注册界面
        """
        return render(request, 'register.html')

3. 定义用户注册路由

1.总路由

urlpatterns = [
    # users
    url(r'^', include('users.urls', namespace='users')),
]

2.子路由

urlpatterns = [
    # 注册
    url(r'^register/$', views.RegisterView.as_view(), name='register'),
]

 

定义用户模型类

1. Django默认用户认证系统

  • Django自带用户认证系统
    • 它处理用户账号、组、权限以及基于cookie的用户会话。
  • Django认证系统位置
    • django.contrib.auth包含认证框架的核心和默认的模型。
    • django.contrib.contenttypes是Django内容类型系统,它允许权限与你创建的模型关联。
  • Django认证系统同时处理认证和授权
    • 认证:验证一个用户是否它声称的那个人,可用于账号登录。
    • 授权:授权决定一个通过了认证的用户被允许做什么。
  • Django认证系统包含的内容
    • 用户:用户模型类、用户认证。
    • 权限:标识一个用户是否可以做一个特定的任务,MIS系统常用到。
    • 组:对多个具有相同权限的用户进行统一管理,MIS系统常用到。
    • 密码:一个可配置的密码哈希系统,设置密码、密码校验。

2. Django默认用户模型类

  • Django认证系统中提供了用户模型类User保存用户的数据。
    • User对象是认证系统的核心。
  • Django认证系统用户模型类位置

    • django.contrib.auth.models.User

       

       

  • 父类AbstractUser介绍

    • User对象基本属性
      • 创建用户(注册用户)必选: username、password
      • 创建用户(注册用户)可选:email、first_name、last_name、last_login、date_joined、is_active 、is_staff、is_superuse
      • 判断用户是否通过认证(是否登录):is_authenticated
    • 创建用户(注册用户)的方法
      user = User.objects.create_user(username, email, password, **extra_fields)
      

        

    • 用户认证(用户登录)的方法
      from django.contrib.auth import authenticate
      user = authenticate(username=username, password=password, **kwargs)
      

        

    • 处理密码的方法
      • 设置密码:set_password(raw_password)
      • 校验密码:check_password(raw_password)

3. 自定义用户模型类

思考:为什么要自定义用户模型类?

  • 观察注册界面会发现,美多商城注册数据必选用户mobile信息
  • 但是Django默认用户模型类中没有mobile字段,所以要自定义用户模型类。

如何自定义用户模型类?

  • 继承自AbstractUser(可通过阅读Django默认用户模型类的源码得知) 。
  • 新增mobile字段。
from django.db import models
from django.contrib.auth.models import AbstractUser

# Create your models here.


class User(AbstractUser):
    """自定义用户模型类"""
    mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')

    class Meta:
        db_table = 'tb_users'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username

  

迁移用户模型类

1. 指定用户模型类

思考:为什么Django默认用户模型类是User?

  • 阅读源代码:'django.conf.global_settings'
    AUTH_USER_MODEL = 'auth.User'
    

结论:

  • Django用户模型类是通过全局配置项 AUTH_USER_MODEL 决定的

配置规则:

AUTH_USER_MODEL = '应用名.模型类名'
# 指定本项目用户模型类
AUTH_USER_MODEL = 'users.User'

2. 迁移用户模型类

1.创建迁移文件

  • python manage.py makemigrations 
  •  

     

 

2.执行迁移文件

  • python manage.py migrate
  •  

     

 

  1. 用户认证系统中的用户模型类,是通过全局配置项 AUTH_USER_MODEL 决定的。
  2. 如果迁移自定义用户模型类,必须先配置 AUTH_USER_MODEL 。

用户注册接口定义

1.注册视图 

class RegisterView(View):
    """用户注册"""

    def get(self, request):
        """
        提供注册界面
        :param request: 请求对象
        :return: 注册界面
        """
        return render(request, 'register.html')

    def post(self, request):
        """
        实现用户注册
        :param request: 请求对象
        :return: 注册结果
        """
        pass

2.总路由 

urlpatterns = [
    # users
    url(r'^', include('users.urls', namespace='users')),
]

3.子路由 

urlpatterns = [
    # 注册
    url(r'^register/$', views.RegisterView.as_view(), name='register'),
]

用户注册后端逻辑

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.配置首页广告路由:绑定命名空间 

# contents
url(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'))

状态保持

说明:

  • 如果需求是注册成功后即表示用户登入成功,那么此时可以在注册成功后实现状态保持
  • 如果需求是注册成功后不表示用户登入成功,那么此时不用在注册成功后实现状态保持

美多商城的需求是:注册成功后即表示用户登入成功

1. login()方法介绍

  1. 用户登入本质:
    • 状态保持
    • 将通过认证的用户的唯一标识信息(比如:用户ID)写入到当前浏览器的 cookie 和服务端的 session 中。
  2. login()方法:
    • Django用户认证系统提供了login()方法。
    • 封装了写入session的操作,帮助我们快速登入一个用户,并实现状态保持。
  3. login()位置:

    • django.contrib.auth.__init__.py文件中。
      
      login(request, user, backend=None)
      

        

  4. 状态保持 session 数据存储的位置:Redis数据库的1号库
     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'))

  

 

 

 

用户名重复注册

 

用户名重复注册后端逻辑

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})

  

用户名重复注册前端逻辑

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);
        })
}

  

手机号重复注册后端逻辑 

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);
        })
}

  

 

  1. 判断用户名和手机号重复注册的核心思想:
    • 使用用户名查询该用户名或者手机号对应的记录是否存在,如果存在,表示重复注册了,反之,没有重复注册。
  2. axios发送异步请求套路:
    • 处理用户交互
    • 收集请求参数
    • 准备请求地址
    • 发送异步请求
    • 得到服务器响应
    • 控制界面展示效果
posted @ 2021-03-30 21:35  lcsp  阅读(340)  评论(0编辑  收藏  举报