一、创建用户模块子应用
1.准备apps
包,用于管理所有应用
2.在apps
包下创建应用users
查看项目导包路径
提示:若要知道如何导入users应用并完成注册,需要知道项目导包路径
- 已知导包路径:
project/meiduo
- 已知 'users'应用所在目录:
project/meiduo/meiduo/apps/users
- 得到导入'users'应用的导包路径是:
meiduo/apps/users
注册用户模块子应用
报错:django.core.exceptions.ImproperlyConfigured: Cannot import 'users'. Check that 'meiduo.apps.users.apps.UsersConfig.name' is correct.
二、追加导包路径
思考:是否可以将注册users应用做的更加简便?直接以应用名users注册
分析:
- 已知导包路径:
project/meiduo
- 已知'users'应用所在目录:
project/meiduo/meiduo/apps/users
- 若要直接以应用名'users'注册,需要一个导包路径:
project/meiduo/meiduo/apps
解决办法,*追加导包路径:project/meiduo/meiduo/apps
追加导包路径
- 目的:简化项目中包的导入和使用
- 原始方式:meiduo.apps.users
- 简洁方式:users
- 步骤
- 添加导包路径:sys.path.insert()
- 重新注册用户模块子应用:'users'
- 查看导包路径
- 通过查看导包路径,可以快速的知道项目中各个包该如何的导入。
- 特别是接手老项目时,可以尽快的适应项目导包的方式。
- 追加导包路径:通过追加导包路径,可以简化某些目录复杂的导包方式。
三、展示用户注册页面
目的:用户注册的发起点事用户注册页面,还需要处理用户注册前端交互逻辑
- 步骤
- 准备用户注册模板文件
- 定义用户注册视图
- 定义用户注册路由
准备用户注册模板文件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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">
</head>
<body>
<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">
<form method="post" class="register_form">
<ul>
<li>
<label>用户名:</label>
<input type="text" name="username" id="user_name">
<span class="error_tip">请输入5-20个字符的用户</span>
</li>
<li>
<label>密码:</label>
<input type="password" name="password" id="pwd">
<span class="error_tip">请输入8-20位的密码</span>
</li>
<li>
<label>确认密码:</label>
<input type="password" name="password2" id="cpwd">
<span class="error_tip">两次输入的密码不一致</span>
</li>
<li>
<label>手机号:</label>
<input type="text" name="mobile" id="phone">
<span class="error_tip">请输入正确的手机号码</span>
</li>
<li>
<label>图形验证码:</label>
<input type="text" name="image_code" id="pic_code" class="msg_input">
<img src="../static/images/pic_code.jpg" alt="图形验证码" class="pic_code">
<span class="error_tip">请填写图形验证码</span>
</li>
<li>
<label>短信验证码:</label>
<input type="text" name="sms_code" id="msg_code" class="msg_input">
<a href="javascript:;" class="get_msg_code">获取短信验证码</a>
<span class="error_tip">请填写短信验证码</span>
</li>
<li class="agreement">
<input type="checkbox" name="allow" id="allow">
<label>同意”美多商城用户使用协议“</label>
<span class="error_tip">请勾选用户协议</span>
</li>
<li class="reg_sub">
<input type="submit" value="注 册">
</li>
</ul>
</form>
</div>
</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 Reserved</p>
<p>电话:010-****888 京ICP备*******8号</p>
</div>
</body>
</html>
定义用户注册试图
from django.shortcuts import render
from django.views import View
# Create your views here.
class RegisterView(View):
# 用户注册
def get(self,request):
# 提供用户注册页面
return render(request, 'register.html')
定义用户注册路由
总路由:
"""meiduo URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('users.urls', namespace='users'))
]
子路由:
from django.urls import path
from . import views
# from views import RegisterView
urlpatterns = [
# 用户注册:reverse(users:register)='/register/'
path('register/', views.RegisterView.as_view(), name='register')
]
页面展示:
遇到问题,报错:django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.
这个错误提示是在 Django 的 URL 配置中,当你尝试使用 include()
函数引入其他 URL 配置时,没有正确设置命名空间(namespace)和应用名称(app_name)所导致的。从 Django 1.9 开始,当你使用 include()
时,如果指定了命名空间,那么同时也需要指定 app_name
在 urls.py
文件中设置 app_name
假设你在 users/urls.py
文件中定义了一系列的 URL 模式,并且你想在项目的根 urls.py
文件中包含这些 URL。你可以在 users/urls.py
文件的 urlpatterns
所在的 AppConfig
类中(但通常这是不必要的,因为 AppConfig
与 URL 配置不直接相关),或者在 users/urls.py
文件的顶部直接设置 app_name
变量:
四、定义用户模型类
4.1 Django默认用户认证系统
- Django自带用户认证系统:它处理用户账号、组、权限以及基于cookie的用户会话。
- Django认证系统位置
django.contrib.auth
包含认证框架的核心和默认的模型。django.contrib.contenttypes
是Django内容类型系统,它允许权限与你创建的模型关联。
- Django认证系统同时处理认证和授权
- 认证:验证一个用户是否它声称的那个人,可用于账号登录。
- 授权:授权决定一个通过了认证的用户被允许做什么。
- Django认证系统包含的内容
- 用户:用户模型类、用户认证。
- 权限:标识一个用户是否可以做一个特定的任务,MIS系统常用到。
- 组:对多个具有相同权限的用户进行统一管理,MIS系统常用到。
- 密码:一个可配置的密码哈希系统,设置密码、密码校验。
4.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)
- 设置密码:
- User对象基本属性
4.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
报错:HINT: Add or change a related_name argument to the definition for 'users.User.user_permissions' or 'auth.User.user_permissions'.
看到这样的提示时,通常意味着在你的项目中存在两个模型(或多个)都有相同名称的反向关系(reverse relation),这导致 Django 在内部处理这些关系时产生冲突。在你的情况下,冲突发生在 users.User.user_permissions
和 auth.User.user_permissions
上,这通常是因为你自定义了 User
模型并且继承了 Django 的 AbstractUser
(或类似地,通过其他方式扩展了 auth.User
),但同时又保留了默认的 auth.User
模型在项目中
如果你自定义了 User
模型并希望完全替代 Django 自带的 auth.User
,你需要在你的 settings.py 文件中设置 AUTH_USER_MODEL
为你的自定义 User
模型,
即自定义模型类后不能直接迁移
4.4 迁移用户模型类
1. 指定用户模型类
思考:为什么Django默认用户模型类是User?
- 阅读源代码:'django.conf.global_settings'
AUTH_USER_MODEL = 'auth.User'
结论:Django用户模型类是通过全局配置项 AUTH_USER_MODEL 决定的
配置规则:
AUTH_USER_MODEL = '应用名.模型类名'
# 指定本项目用户模型类
AUTH_USER_MODEL = 'users.User'
解决:将AUTH_USER_MODEL = "auth.User"复制到dev.py(settings.py)配置文件中,并将auth改为users
再次报错:ValueError: Dependency on app with no migrations: users(改完再执行迁移)
解决:执行python managy.py makemigrations生成迁移文件(admin、auth等子应用已生成)
2. 迁移用户模型类
1.创建迁移文件:python manage.py makemigrations
2.执行迁移文件:python manage.py migrate
3. 知识要点
- Django自带用户认证系统,核心就是User对象,并封装了一系列可用的方法和属性。
- Django用户认证系统包含了一系列对用户的操作,比如:模型类,认证,权限,分组,密码处理等。
- Django用户认证系统中的用户模型类可以自定义,继承自AbstractUser。
- Django用户认证系统说明文档
- 用户认证系统中的用户模型类,是通过全局配置项 AUTH_USER_MODEL 决定的。
- 如果迁移自定义用户模型类,必须先配置 AUTH_USER_MODEL
学习导航:http://www.xqnav.top