Django Blog - 04. 用户账户

Django提供了一个强大的内置用户认证系统,其中的用户对象,包含如下信息:

  • username
  • password
  • email
  • first_name
  • last_name
    通过使用该用户对象,我们就可以实现登录(login)、注销(logout)和注册(signup)功能。

登录

Django 提供了一个默认的用作登录页的 LoginView,实现登录功能,我们需要做的只有三件事:

  1. 在项目的 urls.py 文件中增加一条认证系统的路由
  2. 提供一个登录模板文件
  3. 更新 项目的 settings.py 文件,配置 LOGIN_REDIRECT_URL 值

首先,更新 blog_prj/urls.py 文件,代码如下:

1
2
3
4
5
6
7
8
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')),
path('', include('blog.urls')),
]

接着,正如 LoginView 的文档中描述,默认情况下 Django 会在 templates 目录下查找名为 registration 的目录,并在该目录中查找login.html文件作为登录表单。创建 templates/registration/login.html,代码如下:

1
2
3
4
5
6
7
8
9
{% extends 'base.html' %}

{% block content %}
<h2>Login</h2>
<form action="" method="post">{% csrf_token %}
{% form.as_p %}
<button type="submit">Login</button>
</form>
{% endblock content %}

最后,修改 blog_prj/settings.py文件,指定登录成功后的重定向 URL,代码如下:

1
LOGIN_REDIRECT_URL = 'home'

重启服务后访问http://127.0.0.1:8000/accounts/login/页面,会看到如下登录页面:
upload successful

is_authenticated 属性

通过is_authenticated属性可以判断用户是否已经登录,修改templates/base.html文件,代码如下:

1
2
3
4
5
6
7
8
9
10
...
</header>
{% if user.is_authenticated %}
<p>Hi {{ user.username }}!</p>
{% else %}
<p>You are not logged in.</p>
<a href="{% url 'login' %}">login</a>
{% endif %}
{% block content %}
...

注销

修改base.html文件,增加登录的链接,代码如下:

1
2
3
4
5
...
{% if user.is_authenticated %}
<p>Hi {{ user.username }}!</p>
<p><a href="{% url 'logout' %}">logout</a></p>
...

更新blog_prj/settings.py文件,增加注销之后的重定向 URL:

1
2
LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'

注册

为设计鲁棒性好的认证系统,我们可以在 Django 提供的 UserCreationForm基础上,创建新的 app accounts

1
(venv) ➜  blog git:(master) ✗ python manage.py startapp accounts

blog_prj/settings.py

修改 blog_prj/settings.py文件,在INSTALLED_APPS增加新的 app:

1
2
3
4
5
6
7
8
9
10
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
'accounts',
]

blog_prj/urls.py

接下来,更新blog_prj/urls.py,增加新的 url 配置:

1
2
3
4
5
6
7
8
9
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')),
path('accounts/', include('accounts.urls')),
path('', include('blog.urls')),
]

urls.py

创建 accounts/urls.py文件,代码如下:

1
2
3
4
5
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.SignUpView.as_view(), name='signup'),
]

views

创建accounts/views.py,代码如下:

1
2
3
4
5
6
7
8
from django.contrib.auth.forms import UserCreationForm 
from django.urls import reverse_lazy
from django.views import generic

class SignUpView(generic.CreateView):
form_class = UserCreationForm
success_url = reverse_lazy('login')
template_name = 'signup.html'

signup.html

创建templates/signup.html文件,代码如下:

1
2
3
4
5
6
7
8
{% extends 'base.html' %}
{% block content %}
<h2>Sign up</h2>
<form method="post">{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>
{% endblock %}

运行服务之后,如下图所示:
upload successful