文章目录
- 一、创建用户模块子应用
- 1.1 新建apps包
- 1.2 新建子应用
- 1.3 查看导包路径
- 1.4 注册子应用
- 二、追加导包路径
- 2.1 为什么要追加导包路径
- 2.2 查看当前的导包根路径
- 2.3 追加导包路径
- 三、展示用户注册页面
- 3.1 编写html代码
- 3.2 编写视图文件代码
- 3.3 定义路由
- 3.3.1 项目主路由
- 3.3.2 用户模块子路由
- 3.3.3 访问用户注册页面
- 3.3 命名空间
- 四、用户模型类
- 4.1 定义用户模型类
- 4.1.1 方案一:自定义用户模型类
- 4.1.2 方案二:使用django用户认证系统的用户模型类
- 4.1.3 Django默认用户认证系统
- 4.1.4 Django默认用户模型类
- 4.1.5 自定义用户模型类
- 4.1.6 开发配置文件dev.py中指定自定义的用户模型类
- 4.2 迁移用户模型类
- 4.2.1 第一次迁移
- 4.2.2 重启项目,没有错误了
- 4.2.3 vscode 连接数据库
- 4.2.4 查看自定义数据表
一、创建用户模块子应用
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)
输出列表
[‘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', # 注册子应用
]
二、追加导包路径
2.1 为什么要追加导包路径
- 可以尽快的适应接过来的项目
- 通过追加导包路径,可以简化某些目录复杂的导包方式
2.2 查看当前的导包根路径
import os,sysy
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#查看项目BASE_DIR(自我认为是跟路径)
print(BASE_DIR)
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', # 注册子应用
]
三、展示用户注册页面
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 src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> -->
<script type="text/javascript" src="../static/js/vue_2.6.14.min.js"></script>
<!-- <script type="text/javascript" src="{{ static('js/vue_2.6.14.min.js') }}"></script> -->
<script type="text/javascript" src="{{ static('js/axios_0.21.1.min.js') }}"></script>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<!-- Vue需要控制整个页面,id="app" -->
<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">
<!-- 前端需要用submit事件监听用户是否提交表单。v-cloak限定页面等待所有变量渲染成功再一起展示给用户,避免用户看到前端页面源码 -->
<form method="post" class="register_form" @submit="on_submit" v-cloak>
<!-- csrf隐藏域,用于通过后端服务器的csrf验证 -->
{{ csrf_input }}
<ul>
<li>
<label for="">用户名:</label>
<!-- v-model用于接收用户数据 @blur用于定义鼠标失去焦点事件 -->
<input type="text" v-model="username" @blur="check_username" name="username" id="user_name">
<!-- v-show布尔型,用于显示用户名是否合法的判断结果,{{ 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">
<!-- 复选框checkbox没有blur事件,状态改变使用change事件 -->
<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>
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')
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')),
]
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'),
]
3.3.3 访问用户注册页面
没有css好丑啊
3.3 命名空间
四、用户模型类
4.1 定义用户模型类
目的:迁移建表,并以ORM面向对象的形式增删改查用户数据
4.1.1 方案一:自定义用户模型类
- 优点:灵活,一般用于扩充django默认的
- 缺点:考虑很难周全,设计工程庞大
4.1.2 方案二:使用django用户认证系统的用户模型类
- 优点:拿来可用,关联好了庞大的用户体系,极大节省开发周期和成本
- 缺点:灵活性差点
4.1.3 Django默认用户认证系统
- Django自带用户认证系统:它处理用户账号、组、权限以及基于cookie的用户会话。
- Djang认证系统位置
- django.contrib.auth 包含认证框架的核心和默认的模型。
- django.contrib.contenttypes 是 Django内容类型系统,它允许权限与你创建的模型关联。
- Django认证系统同时处理认证和授权
- 认证:验证一个用户是否它声称的那个人,可用于账号登录。
- 授权:授权决定一个通过了认证的用户被允许做什么。
- Django认证系统包含的内容
- 用户:用户模型类、用户认证。
- 权限:标识一个用户是否可以做一个特定的任务,MIS系统常用到。
- 组:对多个具有相同权限的用户进行统一管理,M系统常用到。
- 密码:一个可配置的密码哈希系统,设置密码、密码校验。
4.1.4 Django默认用户模型类
4.1.5 自定义用户模型类
- 思考:为什么要自定义用户模型类?
- 观察注册界面会发现,商城注册数据中必选用户mobile信息
- 但是 Django默认用户模型类中没有mobile字段,所以要自定义用户模型类
- 如何自定义用户模型类?
- 继承自AbstractUser(可通过阅读Django默认用户模型类的源码得知)
- 新增mobile字段
- 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
报错,需要在配置文件中指定用户自定义模型类
4.1.6 开发配置文件dev.py中指定自定义的用户模型类
# 指定自定义的用户模型类,值的语法为:'z子应用.用户模型类'
AUTH_USER_MODEL = 'users.User'
报错:需要迁移
4.2 迁移用户模型类
4.2.1 第一次迁移
- 生成迁移文件
(meiduo_mall) PS E:\projects\meiduo_project\meiduo_mall> python manage.py makemigrations - 迁移数据库
(meiduo_mall) PS E:\projects\meiduo_project\meiduo_mall> python manage.py migrate
4.2.2 重启项目,没有错误了
4.2.3 vscode 连接数据库
4.2.4 查看自定义数据表