Django用户认证

    django的用户认证有很多方法,可以自己写,也有很多第三方的模块。本文记录的是使用Django自带的认证模块的方法,不需要任何其他第三方的包。

    1、基本配置

    新建好project后,检查settings.py,确保INSTALLED_APPS和MIDDLEWARE中,包含以下模块

INSTALLED_APPS = [
    # 其它应用列表...
    'django.contrib.auth',
    'django.contrib.contenttypes',
]
MIDDLEWARE = [
    # 其它中间列表...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
]

     2、添加必要文件

    新建一个app,取名为users,并在settings.py的INSTALLED_APPS中加入'users'

    新建文件夹templates,在settings.py中修改指定templates的路径:

TEMPLATES = [
    {
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        #其他配置
    },
]

    在users目录和templates目录中加入相关的模型和模板文件,最后整个工程的结构如下:

Django用户认证_第1张图片

    下面介绍各个文件的作用和具体内容:

    (1)users/models.py

    自定义的用户模型,继承AbstractUser,获得username、password、email、first_name、last_name等属性,可以自己添加相关的属性。

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import AbstractUser

# Create your models here.

class User(AbstractUser):
	nick_name = models.CharField(max_length=50, blank=True)

	class Meta(AbstractUser.Meta):
		pass

    此外,还需在settings.py中设置认证的用户模型,并对语言和时区进行修改。

LANGUAGE_CODE = 'zh-hans' #修改
TIME_ZONE = 'Asia/Shanghai' #修改
AUTH_USER_MODEL = 'users.User' #添加

     修改好之后,执行python manage.py makemigrations 和 python manage.py migrate命令,更新数据库

    (2)注册部分:users/forms.py和register.html

     Django 用户系统内置了登录、修改密码、找回密码等视图,但是唯独用户注册的视图函数没有提供,这一部分需要我们自己来写。

     首先,新建注册需要显示的表单模型:users/forms.py

     继承自UserCreationForm,但需对用户模型、显示的field内容进行修改。(密码和密码确认不用修改,会自动显示)

#coding: utf-8
from django.contrib.auth.forms import UserCreationForm
from .models import User

class RegisterForm(UserCreationForm):
	class Meta(UserCreationForm.Meta):
		model = User #表单对应的模型
		fields =("username", "email") #需要渲染的控件。默认有用户名、密码、密码确认,此处增加email

    其次,新建注册页面的html模板templates/registration/register.html




	
	
	
	

	注册
	


	

注册

{% csrf_token %} {% for field in form %} {{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %}

{{ field.help_text|safe }}

{% endif %} {% endfor %}

    在users/views.py中,新建注册对应的视图函数,并把上面的RegisterForm模型传给html模板

def register(request):
	if request.method == 'POST':
		form = RegisterForm(request.POST)

		if form.is_valid():
			form.save()
			return redirect('/')

	else:
		form = RegisterForm()
	return render(request, 'registration/register.html', context={'form': form})

    最后,在urls.py中添加注册的url:

    learn_auth/urls.py:

from django.conf.urls import url, include
from django.contrib import admin
from users import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^users/', include('users.urls')),
    url(r'^users/', include('django.contrib.auth.urls')),
    url(r'^$', views.index, name='index'),
]

    users/urls.py:

from django.conf.urls import url
from . import views

app_name = 'users'

urlpatterns = [
	url(r'^register/', views.register, name='register')
]

   至此,启动服务器,访问localhost:8000/users/register即可进行注册了,并会自动带有错误提示功能。效果如下图(注册完成后,跳转至"/",但该功能未实现,会报错,但实际上已经注册成功,可以打开admin页面查看用户信息是否已经加入数据库)

Django用户认证_第2张图片 Django用户认证_第3张图片

    (3)登录部分:login.html

    Django 自带有登录的视图函数,url模式在django.contrib.auth.urls中,在工程的urls.py中添加该url即可访问到

url(r'^users/', include('django.contrib.auth.urls'))

    自带的视图函数会自动检查数据库,给出登录结果,我们要做的就是提供一个模板文件,用以输入信息和显示登录结果。

    登录模块默认调用templates/registration/login.html模块,因此,需要在registration目录下新建login.html




    
    
    
    登录
    
    


登录

{% csrf_token %} {{ form.non_field_errors }} {% for field in form %} {{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %}

{{ field.help_text|safe }}

{% endif %} {% endfor %}
没有账号?立即注册

    新建index.html,在其中判断用户是否已登录,若未登录则给出登录连接




    
    
    
    首页
    


Django Auth Example

{% if user.is_authenticated %}

你已登录,欢迎你:{{ user.username }}

{% else %}

你还没有登录,请 或者

{% endif %}

    (4)注销部分:注销不需要模板,直接调用{% url 'users:register' %}即可。

    (5)修改密码部分:password_change_form.html和password_change_done.html

    当用户需要修改密码时,调用的自带视图函数地址为{% url 'password_change' %}?next={{ request.path }}

    需要做的,是添加修改页面和修改成功页面两个html模板password_change_form.html和password_change_done.html。




    
    
    
    修改密码
    
    


Django Auth Example

修改密码

{% csrf_token %} {{ form.non_field_errors }} {% for field in form %} {{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %}

{{ field.help_text|safe }}

{% endif %} {% endfor %}



    
    
    
    密码修改成功
    


Django Auth Example

密码修改成功!

     (6)重置密码:password_reset_form.html、password_reset_confirm.html、  password_reset_done.html、 password_reset_complete.html

    一般重置密码流程为:用户点击“忘记密码”,页面跳转到reset_form.html,输入邮箱和相关信息,点击提交,页面跳转到reset_done页面。后台发送重置邮件给用户,并提供重置密码的页面地址,用户打开reset_confirm页面,设置新的密码并提交,页面跳转到reset_complete页面。

    django自带发邮件的功能,只需要在settings.py中进行相关配置,如下面的配置是把邮件发送给终端

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

    调用自带重置密码的url:{% url 'password_reset' %}

    reset_form和reset_conform的主要部分的内容如下(reset_done和reset_complete只是简单的静态提示内容)

    password_reset_form.html :

{% csrf_token %} {{ form.non_field_errors }} {% for field in form %} {{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %}

{{ field.help_text|safe }}

{% endif %} {% endfor %}

    password_reset_confirm.html

{% csrf_token %} {{ form.non_field_errors }} {% for field in form %} {{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %}

{{ field.help_text|safe }}

{% endif %} {% endfor %}

    

 (7)关于注册、登录、注销后的跳转问题

    注册、登录、注销等操作后,一般希望页面跳回到原先访问的地方,而不是跳到其他页面。解决方法是在url中添加一个next参数:

你还没有登录,请 或者

    其中,在login时,因为调用视图函数后,会先访问login.html,并把next参数带过去,而后提交表单给视图函数,此时是一次新的调用,需要把next参数再带回去。方法是在表单后面添加一个hidden的输入

               
{% csrf_token %} {{ form.non_field_errors }} {% for field in form %} {{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %}

{{ field.help_text|safe }}

{% endif %} {% endfor %}

     其次,对于用户直接在地址栏输入登录等页面地址的情况,在settings.py中设置默认跳转到首页

LOGOUT_REDIRECT_URL = '/' #没有next参数时的默认注销后跳转地址
LOGIN_REDIRECT_URL = '/' #没有next参数时的默认登录后跳转地址

    3、扩展

    自带的模块只能通过用户名和密码来认证,如果想要登录时可以通过邮件等其他方式来认证,需要自定义认证模块。

    在users目录下新建backends.py,实现authenticate和get_user方法

from .models import User

class EmailBackend(object):
    def authenticate(self, request, **credentials):
        # 要注意登录表单中用户输入的用户名或者邮箱的 field 名均为 username
        email = credentials.get('email', credentials.get('username'))
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            pass
        else:
            if user.check_password(credentials["password"]):
                return user

    def get_user(self, user_id):
        """
        该方法是必须的
        """
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

       配置settings.py:

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'users.backends.EmailBackend',
)

 

    参考文献:https://www.zmrenwu.com/post/50/

你可能感兴趣的:(Django)