Django 中自定义用户模型及集成认证授权功能总结
1. 概述
Django 中的 django.contrib.auth 应用提供了完整的用户及认证授权功能。
Django 官方推荐基于内置 User 数据模型创建新的自定义用户模型,方便添加 birthday 等新的用户字段和功能。
本文包含的内容有:
- 介绍在 Django 中如何自定义用户模型,并集成到系统。
- 定制
django.contrib.auth应用使用的模板文件。 - 在系统中集成认证与授权功能。
以下所有示例在 Python 3.8.2 + Django 2.1 中实现。
2. 自定义用户模型
2.1. 创建认证与授权相关的单独应用 accounts
$ python manage.py startapp accounts
将应用添加到项目中:
# project_dir/settings.py
INSTALLED_APPS = [
# Local
'accounts.apps.AccountsConfig',
#...
]
2.2. 创建自定义用户模型 CustomUser
Django 官方文档中推荐基于 AbstractBaseUser 创建自定义用户模型,但是一般基于 AbstractUser 创建再方便。
本命中的自定义 CustomUser 中新增了字段 birthday。
# accounts/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
birthday = models.DateField(null=True, blank=True)
2.3. 集成自定义用户模型
通过 AUTH_USER_MODEL 告诉系统新的用户模型:
# project_dir/settings.py
AUTH_USER_MODEL = 'accounts.CustomUser'
之后可通过 get_user_model() 获取该自定义用户模型:
# in view or model files
from django.contrib.auth import get_user_model
CustomUser = get_user_model()
django.contrib.auth 应用已实现了完整的 login, logout 功能,并已在 django.contrib.auth.urls 中定义了 login, logout, password_change, password_change_done, password_reset, password_reset_done, password_reset_confirm, password_reset_complete 等 URL。
将 django.contrib.auth.urls 集成到项目中:
# project_dir/urls.py
from django.urls import path, include
urlpatterns = [
path('accounts/', include('django.contrib.auth.urls'),
#...
]
集成后,即可访问 /accounts/login/, /accounts/logout/, /accounts/password_change/ 等功能,同时时视图和模板中也可访问这个 URL 定义:
<!-- in template files -->
<a href="{% url 'login' %}">Login URL</a>
# in view files
from django.urls import reverse, reverse_lazy
login_url = reverse('login')
#in Class Based View:
login_url = reverse_lazy('login')
2.4. 集成自定义用户模型到后台管理界面
后台管理界面中,添加新用户时呈现的表单由 django.contrib.auth.forms.UserCreationForm 提供,而更新用户时呈现的表单由 django.contrib.auth.forms.UserChangeForm 提供。
为自定义用户模型定制这两个表单:
# accounts/forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = ('username', 'email', 'birthday', )
class CustomUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = CustomUser
fields = UserChangeForm.Meta.fields + ( 'birthday', )
注册到 admin 中:
# accounts/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import CustomUser
from .forms import CustomUserCreationForm, CustomUserChangeForm
class CustomUserAdmin(UserAdmin):
model = CustomUser
add_form = CustomUserCreationForm
form = CustomUserChangeForm
list_display = ['email', 'username', 'birthday', 'is_staff']
admin.site.register(CustomUser, CustomUserAdmin)
3. 定制 django.contrib.auth 应用使用的模板文件
3.1. 定义模板文件
django.contrib.auth 中 login, logout, password_change, password_change_done, password_reset, password_reset_done, password_reset_confirm, password_reset_complete 等视图,访问的相应模板需保存在registration/ 目录下,模板文件有: login.html, password_change_done.html, password_change_form.html, password_reset_complete.html, password_reset_confirm.html, password_reset_done.html, password_reset_form.html 等。
默认配置下,模板文件需保存在 <app-name>/templates/<app-name>/registration/ 目录下,如 accounts/templates/accounts/registration/login.html。
对于小项目,可以将模板目录设置为扁平化:
# project_dir/settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # new
#...
}
]
从而模板可以保存在 templates/ 目录中,如 templates/registration/login.html。
模板中可使用 form 变量,例如:
<!-- templates/registration/login.html -->
{% extends 'base.html' %}
{% block title %}Login{% endblock title %}
{% block content %}
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-success ml-2" type="submit">Login</button>
</form>
{% endblock content %}
3.2. 创建注册功能
django.contrib.auth 没有实现 sign up 功能。
基于 CreateView 创建 SignUpView 视图:
# accounts/views.py
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import CustomUser
from .forms import CustomUserCreationForm
class SignupView(CreateView):
#model = CustomUser
form_class = CustomUserCreationForm
template_name = 'signup.html'
success_url = reverse_lazy('login')
添加模板文件:
<!-- templates/signup.html -->
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Signup{% endblock title %}
{% block content %}
<h2>Signup</h2>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-success" type="submit">Signup</button>
</form>
{% endblock content %}
添加应用级别的 URL 配置:
# accounts/urls.py
from django.urls import path
from .views import SignUpView
urlpatterns = [
path('signup/', SignUpView.as_view(), name='signup'),
]
集成到项目级别的 URL 配置中:
# project_dir/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accounts.urls')),
path('accounts/', include('django.contrib.auth.urls')),
#...
]
4. 在系统中集成认证与授权功能
4.1. 认证:要求登录后才能访问
视图应继承加入 LoginRequiredMixin,属性值 login_url 设置当没有登录时,将转向的登录页面地址或 URL name:
# in view files
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from .models import Article
class ArticleDeleteView(LoginRequiredMixin, DeleteView):
model = Article
template_name = 'article_delete.html'
success_url = reverse_lazy('article_list')
login_url = 'login'
4.2. 授权:只有特定的用户或权限才能访问
CBV 中,代码调用入口是 dispatch() 方法,可以在该方法中实现权限验证,当权限不够时抛出异常:
# in view files
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from .models import Article
class ArticleDeleteView(LoginRequiredMixin, DeleteView):
model = Article
template_name = 'article_delete.html'
success_url = reverse_lazy('article_list')
login_url = 'login'
def dispatch(self, request, *args, **kwargs):
obj = self.get_object()
if obj.author != request.user:
raise PermissionDenied()
return super().dispatch(request, *args, **kwargs)
资源
Django 中自定义用户模型及集成认证授权功能总结的更多相关文章
- 阶段5 3.微服务项目【学成在线】_day18 用户授权_10-前端集成认证授权-需求分析
4 前端集成认证授权 4.1 需求分析 截至目前认证授权服务端的功能已基本完成,本章实现前端集成认证授权功能. 前端集成认证授权功能需要作如下工作: 1.前端页面校验用户的身份,如果用户没有登录则跳转 ...
- Django自定义用户认证系统之自定义用户模型
参考文档:http://python.usyiyi.cn/django/topics/auth/customizing.html Django 自带的认证系统足够应付大多数情况,但你或许不打算使用现成 ...
- 5 项目---自定义用户模型以及轮播图图片url返回格式
创建自定义的用户模型类 1. 用命令创建users 应用 2. 将users 注册到settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'd ...
- Django之重写用户模型
django——重写用户模型 Django内建的User模型可能不适合某些类型的项目.例如,在某些网站上使用邮件地址而不是用户名作为身份的标识可能更合理. 1.修改配置文件,覆盖默认的User模型 D ...
- Django1.5 自定义用户模型(总结)
Django系统有自带的超级棒的认证机制,但是默认的用户模型有一点捉急,为了自定义用户模型,看了很多相关的文章,这里做一个总结: 你可以先看一下这篇,对Django的用户模型有一个比较全的了解: 来自 ...
- django中添加用户
在django中添加用户,直接在auth_user表中添加会有问题,因为这里密码是加密的,可以通过manage.py shell加入 创建User: 1 >>> from djang ...
- 解决在django中应用keras模型时出现的ValueError("Tensor %s is not an element of this graph." % obj)问题
用keras训练好模型,再在django初始化加载模型,这个过程没有问题,但是在调用到模型执行model.predict()的时候就报错: raise ValueError("Tensor ...
- .net core gRPC与IdentityServer4集成认证授权
前言 随着.net core3.0的正式发布,gRPC服务被集成到了VS2019.本文主要演示如何对gRPC的服务进行认证授权. 分析 目前.net core使用最广的认证授权组件是基于OAuth2. ...
- YII2中自定义用户认证模型,完成登陆和注册
有些时候我们需要自已定义用户类,操作自已建的用户表,来完成登陆和注册功能. 用户表结构如下,当然可以根据自已的需要添加或删除: CREATE TABLE `tb_user` ( `id` int(11 ...
随机推荐
- IP地址结构分类(包括主机号和网络好计算)
IP地址:互联网上的每个接口的唯一标识. 长度:32bit. 五类不同的互联网地址格式: 各类IP地址范围: 点分十进制:32位的地址通常写成四个十进制数,其中每个整数对应一个字节. 主机号和网络的计 ...
- SpringBoot:三十五道SpringBoot面试题及答案
SpringBoot面试前言今天博主将为大家分享三十五道SpringBoot面试题及答案,不喜勿喷,如有异议欢迎讨论! Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一 ...
- OA|开放获取期刊|掠夺性期刊|DOI|ORCID|图书馆服务|零次文献|信息素质|
OA|开放获取期刊|掠夺性期刊|DOI|ORCID|图书馆服务|零次文献| 信息检索 信息素质是什么? 信息素质是指一个人的信息需求.信息意识.信息知识.信息道德.信息能力方面的基本素质. Some ...
- 自然语言分析工具Hanlp依存文法分析python使用总结(附带依存关系英文简写的中文解释)
最近在做一个应用依存文法分析来提取文本中各种关系的词语的任务.例如:text=‘新中国在马克思的思想和恩格斯的理论阔步向前’: 我需要提取这个text中的并列的两个关系,从文中分析可知,“马克思的思想 ...
- let和const区别
let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. const命令 const声明一个只读的常量.一旦声明,常量的值就不能改变.
- 读书笔记——《在线》
* 2017年10月24日 星期二 晴* ## "在线"是未来世界发展的关键.一个事物是不是符合未来发展的趋势,就是要看它是否在线. 插图 **在线** 正文 作者是王坚,阿里巴巴 ...
- ES6中Map数据结构学习笔记
很多东西就是要细细的品读然后做点读书笔记,心理才会踏实- Javascript对象本质上就是键值对的集合(Hash结构),但是键只能是字符串,这有一定的限制. 1234 var d = {}var e ...
- Tian Tian 菾菾 导游 陪同
自画像系列是梵高的代表作之一,他是一位自学成才的画家,下笔完全自由,主观提取了当时印象派画家学到的技巧,在这幅画中,我们可以看到,颜色在画中的堆叠,色彩与笔在画中表现的形态,都表现出,梵高在他作画中内 ...
- Autowired和Resource区别
@Autowired和@Resource熟悉吧?是不是经常复制粘贴顺手就来,两者都是用来给成员变量自动装载,可是它俩到底有啥区别呢? 1.@Autowired与@Resource都可以用来装配bean ...
- JobScheduler 和 JobService
使用AlarmManager.IntentService和PendingIntent相互配合,创走周期性的后台任务,实现一个完全可用的后台服务还需要手动执行以下操作. 计划一个周期性任务 ...