- 创建用户注册和身份验证系统
- 新建应用程序,包含与处理用户账户相关的所有功能
- 使用django自带的用户身份验证系统来完成工作
- 对模型Topic稍作修改,让每个主题都归属于特定用户
19.4.1 应用程序users
首先使用命令 startapp 创建一个·名为users的应用程序:

19.4.2 将users添加到settings.py中
在settings.py中,将这个新的应用程序添加到INSTALLED_APPS中:
19.4.3 包含users的URL
修改项目根目录中的urls.py,使其包含将为应用程序users定义的URL:

我们添加了一行代码,以包含应用程序users中的文件urls.py。这行代码与任何以单词users打头的URL(如http://xxx/users/login)都匹配。
19.4.4 登录页面
使用Django提供的默认视图login,这个应用程序的URL模式稍有不同。
在目录noways/users/中新建一个名为urls.py的文件,并在其中添加如下代码:
urls.py
'''为应用程序users定义URL模式'''
from django.urls import path,include
1.app_name = 'users'
urlpatterns = [
#包含默认的身份验证URL
2. path('',include("django.contrib.auth.urls")),
]
导入函数path和include,以便包含Django定义的一些默认的身份验证URL。这些默认的URL包含具名的URL模式,如'login'和'logout'。
- 将变量app_name设置成'users',让Django能够将这些URL与其他应用程序URL区分开来,即便是Django提供的默认URL,将其包含在应用程序users的文件中后,也可通过命名空间users进行访问
- 登陆页面的URL模式与URL http://xxxx/users/login/ 匹配(见2.)这个URL中的单词users让django在users/urls.py中查找,而单词login让它将请求发送给Django的默认视图login
a.模板login.html
- 用户请求登录页面时,Django将使用一个默认的视图函数
- 我们依然要为这个页面提供模板
- 默认的身份验证视图在文件夹registration中查找模板,因此需要创建这个文件夹
- 在目录noways/users/中新建一个名为templates的目录,再在这个目录中新建一个名为registration的目录
- 将模板login.html存储到目录noways/users/templates/registration中:

login.html
{% extends "noways_app/base.html"}
这个模板继承了base.html,说明一个应用程序中的模板可继承另一个应用程序中的模板。
{% block content %}
1. {% if form.errors %}
<p>你的用户名和密码没有被正确的提供,请再尝试一次把!</p>
{% endif %}
2. <form method="post" action="{% url 'users:login' %}">
{% csrf_token %}
3. {{ form.as_p }}
4. <button name="submit">注册</button>
5. <input type="hidden" name="next"
value="{% url 'noways_app:index' %}" />
</form>
{% endblock %}
- 如果设置表单的errrors属性,就显示一条错误信息,指出输入的数据与数据库中存储的数据不匹配
- 要让登录视图对表单进行处理,因此将实参action设置为登陆页面的URL。登录视图将一个表单发送给模板。
- 在模板中,我们显示这个表单
- 并添加一个提交按钮
- 包含一个隐藏的表单元素'next',其中的实参value告诉django在用户成功登录后将其重定向到什么地方。在这里我们返回主页。
b.链接到登录页面
在base.html中添加到登陆页面的链接,让所有页面都包含他。用户已登录时,不想显示它的话,就将它嵌套在一个{% if %}标签中:
base.html
<p>
<a href="{% url 'noways_app:index' %}">学习日志</a> -
<a href="{% url 'noways_app:topics' %}">主题</a><!--他与urls.py中名为topics的url模式匹配-->
{% if user.is_authenticated %}
你好!{{user.username}}.
{% else %}
<a href="{% url 'users:login' %}">注册</a>
{% endif %}
</p>
{% block content %}{% endblock content %}
在Django身份验证系统中,每个模板都可使用变量user。这个变量有一个is_authenticated 属性:如果用户已登录,该属性将为True,否则为False。
c.使用登录页面
前面建立了一个用户账户,下面来登录下

19.4.5 注销
现在需要提供一个让用户注销的途径,为此我们在base.html中添加一个注销链接用户单击即可进入一个确认其已注销的页面
a.在base.html中添加注销链接
- {% if user.is_authenticated %}-->确保已登录用户才可看见
base.html
<p>
<a href="{% url 'noways_app:index' %}">学习日志</a> -
<a href="{% url 'noways_app:topics' %}">主题</a><!--他与urls.py中名为topics的url模式匹配-->
{% if user.is_authenticated %}
你好!{{user.username}}.
<a href="{% url 'users:logout' %}">注销</a>
{% else %}
<a href="{% url 'users:login' %}">注册</a>
{% endif %}
</p>
{% block content %}{% endblock content %}
默认的具名注销URL模式为'logout'
b.注销确认页面
- 成功注销--->默认的注销视图使用模板logged_out.html来渲染注销确认页面
- 请将注销确认模板存储到 目录 templates/registration(login.html所在目录)中:
logged_out.html
{% extends "noways_app/base.html" %}
{% block content %}
<p>你已经注销啦!谢谢你的来访!</p>
{% endblock content %}
未设置网站样式,待功能都完善后,再设计网站的样式

19.4.6 注册页面
使用Django提供的表单UserCreationForm但编写自己的视图函数和模板
a.注册页面的URL模式
下面来定义注册页面的URL模式,它也包含在users/urls.py中
urls.py
'''为应用程序users定义URL模式'''
from django.urls import path,include
from django.views import View
from . import views
app_name = 'users'
urlpatterns = [
# 包含默认的身份验证URL
path('',include("django.contrib.auth.urls")),
# 注册页面
path('register/',views.register,name='register'),
]
从users中导入模块views,注册页面的URL模式与URL:http://xxx/users/register/匹配,并将请求发送给函数register()
b.视图函数register()
- 注册页面被请求-->视图函数register()显示一个空的注册表单并在用户提交好的注册表单时对其进行处理--->注册成功---函数让用户自动登录
views.py
from django.shortcuts import render,redirect
# Create your views here.
from django.contrib.auth import login
#导入login(),在用户正确填写了注册信息时让其自动登录
from django.contrib.auth.forms import UserCreationForm
from matplotlib.style import context
def register(request):
'''注册新用户'''
if request.method != 'POST':
#显示空的注册表单
1. form = UserCreationForm()
else:
#处理填写好的表单
2. form = UserCreationForm(data=request.POST)
3. if form.is_valid():
4. new_user = form.save()
#让用户自动登录,在重定向到主页
5. login(request,new_user)
6. return redirect('noways_app:index')
#显示空表单或指出表单无效
context = {'form':form}
return render(request,'registration/register.html'.context)
- !=POST->创建一个UserCreationForm实例,且不给他提供任何初始数据
- ==POST-->根据提交的数据来创建UserCreationForm实例
- 检查数据是否有效
- 方法save()返回新创建的用户对象,我们将它赋给了new_user且将用户名和密码保存到数据库中
- 保存用户的信息后调用函数login()并传入对象request和new_user->为用户创建有效的会话,从而让其自动登录
- 将用户重定向到主页,且主页的页眉显示一条个性化的问候语提醒用户注册成功
- 函数的末尾渲染了注册页面:要么显示一个空表单要么显示提交的无效表单
C.注册模板
保存到login.html所在目录中
register.html
{% extends "noways_app/base.html" %}
{% block content %}
<form method="post" action="{% url 'users:register' %}">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">注册</button>
<input type="hidden" name="next"
value="{% url 'noways_app:index' %}" />
</form>
{% endblock content%}
D.链接到注册页面
在用户未登录时显示到注册页面的链接:
base.html
<p>
<a href="{% url 'noways_app:index' %}">学习日志</a> -
<a href="{% url 'noways_app:topics' %}">主题</a><!--他与urls.py中名为topics的url模式匹配-->
{% if user.is_authenticated %}
你好!{{user.username}}.
<a href="{% url 'users:logout' %}">注销</a>
{% else %}
<a href="{% url 'users:register' %}">注册</a>
<a href="{% url 'users:login' %}">登录</a>
{% endif %}
</p>
{% block content %}{% endblock content %}
如此一来,已登录的用户看到的是个性化的问候语和注销链接,而未登录的看到的是注册链接和登录链接


文章评论