首页 技术 正文
技术 2022年11月15日
0 收藏 647 点赞 2,601 浏览 5562 个字

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.pyfrom django.db import models
from django.contrib.auth.models import AbstractUserclass 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_modelCustomUser = 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_lazylogin_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, UserChangeFormfrom .models import CustomUserclass 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 UserAdminfrom .models import CustomUser
from .forms import CustomUserCreationForm, CustomUserChangeFormclass 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.pyTEMPLATES = [
{
'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_lazyfrom .models import CustomUser
from .forms import CustomUserCreationFormclass 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 pathfrom .views import SignUpViewurlpatterns = [
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 filesfrom django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDeniedfrom .models import Articleclass 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 filesfrom django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDeniedfrom .models import Articleclass 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)

资源

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,494
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,295