美多商城-Django框架学习——项目配置(1)

阶段一

完成了项目创建还有用户注册

1、项目的创建

  1. 在码云上创建一个项目仓库
  2. 在本地创建一个文件夹然后用Pycharm打开
  3. 从码云上拉取项目 git clone 自己的HTTPS
    美多商城-Django框架学习——项目配置(1)_第1张图片
  4. 为pycharm安装django框架
  5. 创建美多商城django工程
django-admin startproject meiduo_mall
  1. 创建完成美多商城-Django框架学习——项目配置(1)_第2张图片
    至此项目创建完毕

2、项目配置

  1. 更改配置方式 新建setting的python文件夹,创建dev.py文件将setting.py文件内容复制到dev文件中,将dev文件作为此项目的配置文件,在创建prod.py作为生产环境配置文件
    美多商城-Django框架学习——项目配置(1)_第3张图片
  2. 配置JinJa2模板引擎
    $ pip install Jinja2
TEMPLATES = [
    {
     
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [os.path.join(BASE_DIR,'templates'),],
        'APP_DIRS': True,
        'OPTIONS': {
     
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
            'environment':'app.base_jinja2.environment'            
        },
    },
    {
     
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
     
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    }   
]
  1. 补充Jinja2模板引擎环境 新建Jinja2.py文件 并且输入
from jinja2 import Environment
from django.urls import reverse
from django.contrib.staticfiles.storage import staticfiles_storage


def jinja2_environment(**options):
    """jinja2 环境"""

    # 创建环境对象
    env = Environment(**options)
    # 自定义语法 {
     {static('静态文件相对路径')}} {
     {url('路由命名空间')}}
    env.globals.update({
     
        'static': staticfiles_storage.url,  # 获取静态文件前缀
        'url': reverse,  # 反向解析
    })
    # 返回环境对象
    return env
"""
确保可以使用模板引擎中的{
     { url('') }} {
     { static('') }}这类语句 
"""

在这里插入图片描述

  1. 加载Jinja2模板引擎环境
TEMPLATES = [
    {
     
        'BACKEND': 'django.template.backends.jinja2.Jinja2',  # jinja2模板引擎
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
     
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
            # 补充Jinja2模板引擎环境
            'environment': 'meiduo_mall.utils.jinja2_env.jinja2_environment', 
        },
    },
]

3、配置mysql 数据库

  1. 需要在ubuntu里安装Mysql
  2. 创建一个新的数据库
    create database meiduo_mall charset=utf8;
  3. 新增Mysql用户
    create user itcast identified by '123456';
  4. 授权itcast用户访问meiduo_mall数据库
    grant all on meiduo_mall.* to 'itcast'@'%';
  5. 刷新权限
    flush privileges;
  6. 在pycharm中的dev文件中配置Mysql数据库
DATABASES = {
     
    'default': {
     
        'ENGINE': 'django.db.backends.mysql', # 数据库引擎
        'HOST': '127.0.0.1', # 数据库主机
        'PORT': 3306, # 数据库端口
        'USER': 'itcast', # 数据库用户名
        'PASSWORD': '123456', # 数据库用户密码
        'NAME': 'meiduo_mall' # 数据库名字
    },
}

需要安装PyMySQL的驱动程序
美多商城-Django框架学习——项目配置(1)_第4张图片7. 工程同名目录下的 __init__文件中 加入代码

import pymysql

pymysql.version_info = (1, 4, 2, "final", 0)
pymysql.install_as_MySQLdb()

  1. 配置Redis数据库
    安装 django-redis 扩展包
pip install django-redis

配置Redis数据库

CACHES = {
     
    "default": {
      # 默认
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/0",
        "OPTIONS": {
     
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
    "session": {
      # session
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
     
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"

default:

默认的Redis配置项,采用0号Redis库。
session:

状态保持的Redis配置项,采用1号Redis库。
SESSION_ENGINE

修改session存储机制使用Redis保存。
SESSION_CACHE_ALIAS:

使用名为"session"的Redis配置项存储session数据。

  1. 配置工程日志 都是模板直接复制粘贴就行
LOGGING = {
     
    'version': 1,
    'disable_existing_loggers': False,  # 是否禁用已经存在的日志器
    'formatters': {
       # 日志信息显示的格式
        'verbose': {
     
            'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
        },
        'simple': {
     
            'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
        },
    },
    'filters': {
       # 对日志进行过滤
        'require_debug_true': {
       # django在debug模式下才输出日志
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
       # 日志处理方法
        'console': {
       # 向终端中输出日志
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file': {
       # 向文件中输出日志
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(os.path.dirname(BASE_DIR), 'logs/meiduo.log'),  # 日志文件的位置
            'maxBytes': 300 * 1024 * 1024,
            'backupCount': 10,
            'formatter': 'verbose'
        },
    },
    'loggers': {
       # 日志器
        'django': {
       # 定义了一个名为django的日志器
            'handlers': ['console', 'file'],  # 可以同时向终端与文件中输出日志
            'propagate': True,  # 是否继续传递日志信息
            'level': 'INFO',  # 日志器接收的最低日志级别
        },
    }
}

创建保存log文件的文件夹
美多商城-Django框架学习——项目配置(1)_第5张图片

日志记录器的使用

import logging

# 创建日志记录器
logger = logging.getLogger('django')
# 输出日志
logger.debug('测试logging模块debug')
logger.info('测试logging模块info')
logger.error('测试logging模块error')
  1. 配置前端静态文件
    美多商城-Django框架学习——项目配置(1)_第6张图片
    指定文件加载路径 在dev文件里添加
STATIC_URL = '/static/'

# 配置静态文件加载路径
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

配置运行参数
美多商城-Django框架学习——项目配置(1)_第7张图片

然后运行 能显示图片就说明配置的没有错误
美多商城-Django框架学习——项目配置(1)_第8张图片

4、用户注册

展示登录界面

  1. 创建用户模块应用
    美多商城-Django框架学习——项目配置(1)_第9张图片
    需要在Terminal里创建子应用
    需要引用到 manage.py文件 所以创建子模块的命令式
python ../../manage.py startapp users

需要在setting文件里注册用户模块应用
为了方便注册用户模块应用需要追加apps导包路径

# 追加导包路径指向apps
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'users',  # 用户模块应用
]
  1. 展示用户注册界面
    在users/view 文件中创建 RegisterView类 写上get方法
class RegisterView(View):
    def get(self, request):
    	# 返回一个html界面  request 就是当前界面
        return render(request, "register.html")

总路由配置

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    # users
    # 这里include 里是users.urls 不是 users:urls 我在这里一直报错最后才发现
    path('', include('users.urls')),
]

在users目录下创建urls.py文件

from django.urls import path
from . import views

urlpatterns = [
    # 注册用户界面
    path('register/', views.RegisterView.as_view(), name="register"),
]

运行程序
美多商城-Django框架学习——项目配置(1)_第10张图片
3. 用户模型类
定义用户模型类
这个项目用到的字段有 ↓

用户名 密码 手机号 Email 是否是管理员 is_delete
Django 框架默认使用一个 User 模型类, 保存我们有关用户的字段
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) 用户认证的方法

Django 自带用户认证系统
它处理用户账号、组、权限以及基于 cookie 的用户会话
Django 认证系统同时处理认证和授权
认证:验证一个用户是否它声称的那个人,可用于账号登录. 授权:授权决定一个通过了认证的用户被允许做什么. Django 认证系统包含的内容

用户:用户模型类、用户认证. 权限:标识一个用户是否可以做一个特定的任务,MIS 系统常用到.
组:对多个具有相同权限的用户进行统一管理,MIS 系统常用到. 密码:一个可配置的密码哈希系统,设置密码、密码校验. # 导入
from django.contrib.auth import authenticate

进行认证校验, 查看用户是否是声明的那一个
user = authenticate(username=username, password=password, **kwargs) 处理密码的方法

设置密码:set_password(raw_password)
校验密码:check_password(raw_password)

通过观察我们发现 注册数据中需要用户的手机号mobile信息,但是默认的django默认用户模型类中没有mobile字段,所以要自定义用户模型类

自定义用户模型类 (继承AbstractUser)

from django.db import models
# Create your models here.
from django.contrib.auth.models import AbstractUser
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
    # 在str魔法方法中 返回用户名称
    def __str__(self):
        return self.username

要指定用户模型类

# django 中默认使用 auth 子应用下面的 User 作为用户模型类
# 默认: 
AUTH_USER_MODEL = 'auth.User'
# Django 用户模型类是通过全局配置项 AUTH_USER_MODEL 决定的

因为我们重写了用户模型类, 所以我们需要重新指定默认的用户模型类:

设置格式:
AUTH_USER_MODEL = '应用名.模型类名'

在dev文件中更改默认的用户模型类 格式:

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

下一步 迁移用户模型类
首先生成迁移文件
美多商城-Django框架学习——项目配置(1)_第11张图片

执行迁移文件

python manage.py migrate

美多商城-Django框架学习——项目配置(1)_第12张图片

这样就创建成功了

用户注册业务

  1. 业务分析美多商城-Django框架学习——项目配置(1)_第13张图片

前端代码.html
能大概看懂就行,毕竟不是做前端开发
输入框焦点消失,发送axios请求给后端,后端返回判断结果给前端,前端判断是否显示后端给的数据。大概就是这样


<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<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') }}">

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

head>
<body>
<div id="app">
    <div class="register_con">
        <div class="l_con fl">
            <a href="index.html" class="reg_logo"><img src="../static/images/logo.png">a>
            <div class="reg_slogan">商品美 · 种类多 · 欢迎光临div>
            <div class="reg_banner">div>
        div>
        <div class="r_con fr">
            <div class="reg_title clearfix">
                <h1>用户注册h1>
                <a href="login.html">登录a>
            div>
            <div class="reg_form clearfix">
                {#v-cloak 取消因为Vue加载过慢的显示问题#}
                <form method="post" class="register_form" @submit="on_submit" v-cloak>
                    {
    { csrf_input }}
                    <ul>
                        <li>
                            <label>用户名:label>
                            {#@blur焦点#}
                            <input type="text" name="username" id="user_name" v-model="username" @blur="check_username">
                            <span class="error_tip" v-show="error_name">[[error_name_message]]span>
                        li>
                        <li>
                            <label>密码:label>
                            <input type="password" name="password" id="pwd" v-model="password" @blur="check_password">
                            <span class="error_tip" v-show="error_password">请输入8-20位的密码span>
                        li>
                        <li>
                            <label>确认密码:label>
                            <input type="password" name="password2" id="cpwd" v-model="password2"
                                   @blur="check_password2">
                            <span class="error_tip" v-show="error_password2">两次输入的密码不一致span>
                        li>
                        <li>
                            <label>手机号:label>
                            <input type="text" name="mobile" id="phone" v-model="mobile" @blur="check_mobile">
                            <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" v-model="image_code"
                                   @blur="check_image_code">
                            <img :src="image_code_url" alt="图形验证码" class="pic_code" @click="generate_image_code">
                            <span class="error_tip" v-show="error_image_code">[[error_image_code_message]]span>
                        li>
                        <li>
                            <label>短信验证码:label>
                            <input type="text" name="sms_code" id="msg_code" class="msg_input" v-model="sms_code"
                                   @blur="check_sms_code">
                            <a class="get_msg_code" @click="send_sms_code">[[sms_code_tip]]a>
                            <span class="error_tip" v-show="error_sms_code">[[error_sms_code_message]]span>
                            {% if sms_code_errmsg %}
                            <span class="error_tip">{
    { sms_code_errmsg }}span>
                            {% endif %}
                        li>
                        <li class="agreement">
                            <input type="checkbox" name="allow" id="allow" v-model="allow" @change="check_allow">
                            <label>同意”美多商城用户使用协议“label>
                            <span class="error_tip" v-show="error_allow">请勾选用户协议span>
                            {% if register_errmsg %}
                            <span class="error_tip">{
    { register_errmsg }}span>
                            {% endif %}
                        li>
                        <li class="reg_sub">
                            <input type="submit" value="注 册">
                        li>
                    ul>
                form>
            div>
        div>
        <div class="footer no-mp">
            <div class="foot_link">
                <a href="#">关于我们a>
                <span>|span>
                <a href="#">联系我们a>
                <span>|span>
                <a href="#">招聘人才a>
                <span>|span>
                <a href="#">友情链接a>
            div>
            <p>CopyRight © 2016 北京美多商业股份有限公司 All Rights Reservedp>
            <p>电话:010-****888 京ICP备*******8号p>
        div>
    div>
    <script src="{
      { static('js/common.js') }}">script>
    <script src="{
      { static('js/register.js') }}">script>
body>
html>

对应的js文件 主要就是判断输入框里的数据是否合法,是否要在html界面显示对应的提示信息

// 创建vue对象
// 我们才用的ES6语法
let vm = new Vue({
     
    el: '#app', // 通过id选择器找到绑定的html内容
    // 修改Vue读取变量的语法
    delimiters: ['[[', ']]'],
    data: {
      // 数据对象
        // v-model
        username: '',
        password: '',
        password2: '',
        mobile: '',
        allow: '',
        image_code_url: '',
        uuid: '',
        image_code: '',
        sms_code_tip: '获取短信验证码',
        send_flag: false,
        sms_code: '',

        // v-show
        error_name: false,
        error_password: false,
        error_password2: false,
        error_mobile: false,
        error_allow: false,
        error_image_code: false,
        error_sms_code: false,

        // error_message
        error_name_message: '',
        error_mobile_message: '',
        error_image_code_message: '',
        error_sms_code_message: '',

    },
    // vue生命周期 页面加载完成
    mounted() {
     
        //生成图形验证码
        this.generate_image_code();
    },
    methods: {
      // 定义和实现事件方法
        check_sms_code() {
     
            if (this.sms_code.length != 6) {
     
                this.error_sms_code_message = '请填入短信验证码'
                this.error_sms_code = true;
            } else {
     
                this.error_sms_code = false;
            }
        },
        // 发送短信验证码
        send_sms_code() {
     
            if (this.send_flag == true) {
      // 判断是否已经发送短信
                // 避免恶意用户频繁点击获取短信验证码的标签
                return;
            }
            // 校验数据 mobile image_code
            this.check_mobile();
            this.check_image_code();
            if (this.error_mobile == true || this.error_image_code == true) {
     
                this.send_flag = false;
                return;
            }
            this.send_flag = true;// 如果可以运行到这里,立即设置已经发送过短信
            let url = '/sms_codes/' + this.mobile
                + '/?image_code=' + this.image_code
                + '&uuid=' + this.uuid
            axios.get(url, {
     
                responseType: 'json'
            }).then(response => {
     
                if (response.data.code == '0') {
     
                    // 展示倒计时60S
                    let num = 60;
                    let t = setInterval(() => {
     
                        if (num == 1) {
      // 倒计时即将结束
                            // 停止回调函数
                            clearInterval(t);
                            // 还原sms_code_tip的提示文字
                            this.sms_code_tip = '获取短信验证码';
                            // 重新生成图形验证码
                            this.generate_image_code();
                            this.send_flag = false;
                        } else {
     //正在倒计时
                            num -= 1;
                            this.sms_code_tip = num + '秒'
                        }
                    }, 1000)
                } else {
      //
                    if (response.data.code == '4001') {
      // 图形验证码错误
                        this.error_image_code_message = response.data.errmsg;
                        this.error_image_code = true;
                    } else {
      // 4002 短信验证码错误
                        this.error_sms_code_message = response.data.errmsg;
                        this.error_sms_code = true;
                    }
                    this.send_flag = false;
                }
            })
                .catch(error => {
     
                    console.log(error.response);
                    this.send_flag = false;
                })
        },

        // 生成图形验证码的方法:封装的思想,代码复用
        generate_image_code() {
     
            this.uuid = generateUUID();
            this.image_code_url = '/image_codes/' + this.uuid + '/';
        },
        // 校验用户名
        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;
            }
            // 判断用户名是否重复注册
            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);
                    })
            }
        },
        // 校验密码
        check_password() {
     
            let re = /^[0-9A-Za-z]{8,20}$/;
            if (re.test(this.password)) {
     
                this.error_password = false;
            } else {
     
                this.error_password = true;
            }

            if (this.password2 != this.password) {
     
                this.error_password2 = true;
            } else {
     
                this.error_password2 = false;
            }
        },
        // 校验确认密码
        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;
            }
            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);
                    })
            }
        },
        // 校验图形验证码
        check_image_code() {
     
            if (this.image_code.length != 4) {
     
                this.error_image_code_message = '请输入图形验证码';
                this.error_image_code = true;
            } else {
     
                this.error_image_code = false;
            }
        },
        // 校验是否勾选协议
        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_sms_code();
            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;
            }
        }
    }

})

编写后端代码

    def post(self, request):
        """实现用户注册"""
        # 接收参数
        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')

        # 校验参数 判断参数是否齐全
        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('请勾选用户协议')

        # 保存注册数据
        try:
            User.objects.create_user(username=username, password=password, mobile=mobile)
        except DatabaseError:
            return render(request, 'register.html', {
     'register_errmsg': '注册失败'})

        # 响应注册结果
        return http.HttpResponse('注册成功,重定向到首页')

创建首页广告应用 contents

 python ../../manage.py startapp contents

在 Dev 注册app
美多商城-Django框架学习——项目配置(1)_第14张图片

添加主路由

urlpatterns = [
    # content
    path('', include(('contents.urls', 'contents'), namespace='contents')),

]

添加子路由

urlpatterns = [
    # 注册用户界面
    path('', views.IndexView.as_view(), name="index"),
]

然后运行项目 测试能否正常访问
http://127.0.0.1:8000/

修改注册成功后重定向到首页

# 响应注册结果
return redirect(reverse('contents:index'))

然后运行项目按步骤进行注册,注册完成后是否会跳转到首页
美多商城-Django框架学习——项目配置(1)_第15张图片
同时查看数据库是否有用户注册信息
美多商城-Django框架学习——项目配置(1)_第16张图片

状态保持

美多商城-Django框架学习——项目配置(1)_第17张图片
login使用方法

 # 实现状态保持
login(request, user)

再次注册
查看状态保持结果

PS:dev文件的redis数据库ip地址应该是服务器的ip地址

美多商城-Django框架学习——项目配置(1)_第18张图片
在这里插入图片描述

用户名重复注册

美多商城-Django框架学习——项目配置(1)_第19张图片

美多商城-Django框架学习——项目配置(1)_第20张图片
思路就是前端把用户名输入框的数据发送一个ajax请求(就是一个带有参数get请求)后端接收前端这个请求,并且把username提取出来,用这个数据查询数据库这个username的count返回给前端,前端判断count==1就说明这个数据已经存在,就在网页上显示用户名已存在,并且用户名异常设置为true

后端逻辑

class UsernameCountView(View):
    """判断用户名是否重复注册"""

    def get(self, request, username):
        """
        :param request: 请求对象
        :param username: 用户名
        :return: JSON
        """
        # 判断username在表中的个数
        count = User.objects.filter(username=username).count()
        return http.JsonResponse({
     'code': RETCODE.OK, 'errmsg': 'OK', 'count': count})

前端逻辑

 // 校验用户名
        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;
            }
            // 判断用户名是否重复注册
            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);
                    })
            }
        },

设置路由
如果路由中有正则。需要把path换成re_path 其他的应该没有什么变化吧。而且如果用到了\w \d一类的 要加r转义

# 判断用户名是否重复注册
    re_path(r'usernames/(?P\w{5,20})/count/', views.UsernameCountView.as_view()),

测试
美多商城-Django框架学习——项目配置(1)_第21张图片

手机号重复注册

原理和用户名一样
美多商城-Django框架学习——项目配置(1)_第22张图片
后端代码

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

# 路由
# 判断手机号是否重复注册
    re_path(r'mobiles/(?P1[3-9]\d{9})/count/', views.MobileCountView.as_view()),

后端相应的的是json数据

js逻辑

 // 校验手机号
        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;
            }
            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);
                    })
            }
        },

测试
在这里插入图片描述

第一阶段完

你可能感兴趣的:(Python,python,django)