• 【Python百日进阶-WEB开发】Day172 - Django案例:04用户模型类


    一、创建用户模块子应用

    1.1 新建apps包

    在项目主文件夹(第二层meiduo_mall)中创建apps包,用于管理所有的子应用,包中包括或创建 init.py文件

    1.2 新建子应用

    (meiduo_mall) PS E:\projects\meiduo_project\meiduo_mall\meiduo_mall\apps> python …\manage.py startapp users

    1.3 查看导包路径

    import sys
    print(sys.path)
    
    • 1
    • 2

    输出列表
    [‘E:\projects\meiduo_project\meiduo_mall’, ‘c:\python39\python39.zip’, ‘c:\python39\DLLs’, ‘c:\python39\lib’, ‘c:\python39’, ‘E:\projects\meiduo_project\meiduo_mall’, ‘E:\projects\meiduo_project\meiduo_mall\lib\site-packages’]
    说明:

    • 第1项就是当前工程的虚拟环境
    • 最后1项就是虚拟环境的扩展包路径,其中包括django等扩展包
    • 上述列表中的任意一项都可以作为导包的起点,只需从其下级目录开始逐级指定路径就可以了。
      如:用户子应用绝对路径为: ‘E:\projects\meiduo_project\meiduo_mall\meiduo_mall\apps\users’
      导包路径为:‘meiduo_mall.apps.users’

    1.4 注册子应用

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'meiduo_mall.apps.users',   # 注册子应用
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    二、追加导包路径

    2.1 为什么要追加导包路径

    • 可以尽快的适应接过来的项目
    • 通过追加导包路径,可以简化某些目录复杂的导包方式

    2.2 查看当前的导包根路径

    import os,sysy
    BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    #查看项目BASE_DIR(自我认为是跟路径)
    print(BASE_DIR)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.3 追加导包路径

    # 追加导包路径
    sys.path.insert(1, 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',
        # 'meiduo_mall.apps.users',   # 注册子应用
        'users',   # 注册子应用
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    三、展示用户注册页面

    3.1 编写html代码

    在这里插入图片描述

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <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.6.14.min.js">script>
        { static('js/vue_2.6.14.min.js') }}"> -->
        <script type="text/javascript" src="{{ static('js/axios_0.21.1.min.js') }}">script>
        
        <style>
            [v-cloak] {
                display: none;
                }
        style>
    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" alt="">a>
                    <div class="reg_slogan">人美货全div>
                    <div class="reg_banner">div>
                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">
                    
                    <form method="post" class="register_form" @submit="on_submit" v-cloak>
                        
                        {{ csrf_input }}
                        <ul>
                            <li>
                                <label for="">用户名:label>
                                
                                <input type="text" v-model="username" @blur="check_username" name="username" id="user_name">
                                { error_name_message }}用于显示不同类型的错误信息 -->
                                <span class="error_tip" v-show="error_name">[[ error_name_message ]]span>
                            li>
                            <li>
                                <label for="">密码: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 for="">确认密码:label>
                                <input type="password" v-model="password2" @blur="check_password2" name="password2" id="pwd2">
                                <span class="error_tip" v-show="error_password2">两次输入的密码不一样span>
                            li>
                            <li>
                                <label for="">手机号: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 for="">图形验证码:label>
                                <input type="text" v-model="image_code" @blur="check_image_code" name="image_code" id="msg_input">
                                <img v-bind:src="image_code_url" @click='generate_image_code' alt="图形验证码" class="pic_code">
                                <span class="error_tip" v-show="error_image_code">[[ error_image_code_message]]span>
                            li>
                            <li>
                                <label for="">短信验证码label>
                                <input type="text" v-model="sms_code" @blur="check_sms_code" name="sms_code" id="sms_code" class="msg_input">
                                <a @click="send_sms_code" class="get_msg_code">[[ sms_code_tip ]]a>
                                <span class="error_tip" v-show="error_sms_code">[[ error_sms_code_message]]span>
                            li>
                            <li class="agreement">
                                
                                <input type="checkbox" v-model="allow" @change="check_allow" name="allow" id="allow">
                                <label for="">同意“商城用户使用协议”label>
                                <span class="error_tip" v-show="error_allow">请勾选用户协议span>
                            li>
                        ul>
                        <input type="submit" value="注册">
                        {% if register_errmsg %}
                            <span class="error_tip">{{ register_errmsg }}span>
                        {% endif %}
                    form>
                div>
            div>
        div>
        <script type="text/javascript" src="../static/js/common.js">script>
        <script type="text/javascript" src="../static/js/register.js">script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    3.2 编写视图文件代码

    from django.shortcuts import render
    from django.views import View
    
    # Create your views here.
    class ResgisterView(View):
        """ 用户注册 """
        def get(self, request):
            """ 用于提供数据--用户注册页面 """
            return render(request, 'register.html')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.3 定义路由

    3.3.1 项目主路由

    from django.contrib import admin
    from django.urls import path, include
    from meiduo_mall.apps.users import urls as users_urls
    
    urlpatterns = [
        path('admin/', admin.site.urls),
    
        # users
        path('', include(users_urls, namespace='users')),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.3.2 用户模块子路由

    from django.urls import path
    from . import views
    
    app_name = 'users'
    
    urlpatterns = [
        # 用户注册: reverse(users:register) == '/register/'
        path('register/', views.ResgisterView.as_view(), name='register'),  
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.3.3 访问用户注册页面

    在这里插入图片描述
    没有css好丑啊

    3.3 命名空间

    四、用户模型类

    4.1 定义用户模型类

    目的:迁移建表,并以ORM面向对象的形式增删改查用户数据

    4.1.1 方案一:自定义用户模型类

    • 优点:灵活,一般用于扩充django默认的
    • 缺点:考虑很难周全,设计工程庞大

    4.1.2 方案二:使用django用户认证系统的用户模型类

    • 优点:拿来可用,关联好了庞大的用户体系,极大节省开发周期和成本
    • 缺点:灵活性差点

    4.1.3 Django默认用户认证系统

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

    4.1.4 Django默认用户模型类

    在这里插入图片描述

    4.1.5 自定义用户模型类

    1. 思考:为什么要自定义用户模型类?
    • 观察注册界面会发现,商城注册数据中必选用户mobile信息
    • 但是 Django默认用户模型类中没有mobile字段,所以要自定义用户模型类
    1. 如何自定义用户模型类?
    • 继承自AbstractUser(可通过阅读Django默认用户模型类的源码得知)
    • 新增mobile字段
    1. users子应用的models.py
    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 = '用户'   # admin站点中显示
            verbose_name_plural = verbose_name
    
        def __str__(self) -> str:
            return self.username
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    报错,需要在配置文件中指定用户自定义模型类
    在这里插入图片描述

    4.1.6 开发配置文件dev.py中指定自定义的用户模型类

    # 指定自定义的用户模型类,值的语法为:'z子应用.用户模型类'
    AUTH_USER_MODEL = 'users.User'
    
    • 1
    • 2

    报错:需要迁移
    在这里插入图片描述

    4.2 迁移用户模型类

    4.2.1 第一次迁移

    1. 生成迁移文件
      (meiduo_mall) PS E:\projects\meiduo_project\meiduo_mall> python manage.py makemigrations
      在这里插入图片描述
    2. 迁移数据库
      (meiduo_mall) PS E:\projects\meiduo_project\meiduo_mall> python manage.py migrate
      在这里插入图片描述

    4.2.2 重启项目,没有错误了

    在这里插入图片描述

    4.2.3 vscode 连接数据库

    在这里插入图片描述

    4.2.4 查看自定义数据表

    在这里插入图片描述

  • 相关阅读:
    微信小程序自定义顶部导航栏
    lightdb22.3预览-listagg 增强
    《在线编程-Python篇》Python入门 01 输入输出
    判断线程池任务执行完成的方式
    【java_wxid项目】【第七章】【Spring Cloud Alibaba Seata集成】
    【Python基础】面向对象封装 案例(一)
    HTML和CSS如何记忆
    Autosar诊断实战系列21-UDS连续帧(CF)数据接收代码级分析
    Protobuf简介
    六零导航页(LyLme Spage)导航网站源码
  • 原文地址:https://blog.csdn.net/yuetaope/article/details/123003612