本文介绍教程系列中的步骤 5 在 Visual Studio中使用 Django Web 框架。
身份验证是 Web 应用的常见要求。 Visual Studio 中的 Django Web 项目 模板提供了在 Django 项目的 settings.py 文件中进行身份验证所需的所有模块。 本教程系列中的步骤 4 使用此模板创建 Django Web 应用。 在步骤 5 中,你将探索模板的身份验证功能,并处理正在运行的应用中的功能。
在本教程的步骤 5 中,你将了解如何:
- 在 Visual Studio 的 Django Web 项目模板中浏览身份验证流
- 检查支持身份验证过程的代码
- 修改代码以启用对 Django 管理员接口的访问
- 运行 Django Web 应用并使用身份验证功能
先决条件
基于 Django Web 项目 模板(DjangoWeb)的 Visual Studio 解决方案和 Django Web 应用。 步骤 4:使用完整的 Django Web 项目模板 介绍如何创建此应用。
Django Web 应用必须具有超级用户(管理员)帐户。 步骤 4(创建 Django 超级用户) 介绍如何创建超级用户凭据。
有关 Django 模板版本、Visual Studio 项目与 Django 项目以及 Mac 上的 Python 开发的详细信息,请查看本教程系列步骤 1 中的 先决条件 部分。
探索身份验证流程
本部分介绍 Django Web 应用的 Django Web 项目 模板提供的默认身份验证流。
在 Visual Studio 中,选择 调试>启动调试(F5)以启动 Django Web 应用(DjangoWeb)。
当应用在浏览器中打开时,请注意导航栏右侧 登录 选项:
正在运行的 Django 应用具有三个页面选项的导航栏,主页、关于和 联系人,以及 登录 选项。 身份验证配置允许任何用户查看“主页”、“关于”和“联系人”页面上的内容。
对于对 Django Web 应用的身份验证访问,指定的超级用户可以使用 登录 选项,这将打开“登录”页面:
超级用户登录后,他们可以访问网站的受限页面视图并完成管理任务:
超级用户可以使用 注销 选项注销 Django Web 应用,并作为未经身份验证的用户返回到 Django Web 应用的“主页”。
在以下部分中,将修改身份验证配置以支持超级用户的 Django 管理站点访问。
检查身份验证代码
了解 Django Web 应用的常规身份验证功能后,即可检查由 Django Web 项目 模板提供的基础代码:
在 解决方案资源管理器中,展开项目的 app/templates/app 文件夹。 以下步骤查看此文件夹中的多个文件。
打开基本模板文件,layout.html。 滚动到
<div class="navbar ...>
元素并找到{% include app/loginpartial.html %}
标记。{% include %}
标记指示 Django 的模板化系统在包含模板中此时所含的文件内容中进行拉取。打开 loginpartial.html 文件。 观察此模板如何使用条件标记
{% if user.is_authenticated %}
以及{% else %}
标记来呈现不同的 UI 元素,具体取决于用户是否已进行身份验证:{% if user.is_authenticated %} <form id="logoutForm" action="/logout" method="post" class="navbar-right"> {% csrf_token %} <ul class="nav navbar-nav navbar-right"> <li><span class="navbar-brand">Hello {{ user.username }}!</span></li> <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li> </ul> </form> {% else %} <ul class="nav navbar-nav navbar-right"> <li><a href="{% url 'login' %}">Log in</a></li> </ul> {% endif %}
启动应用时,不会对超级用户进行身份验证,模板代码仅呈现 登录 链接。 链接以 Django 项目的 URL 文件(DjangoWeb/DjangoWeb/urls.py)中指定的网站相对“登录”路径为目标,如 步骤 4(检查 URL 路由模式)中所述。 “login”路由被映射到标记为
django.contrib.auth.views.login
的视图,视图接收以下数据:{ 'template_name': 'app/login.html', 'authentication_form': app.forms.BootstrapAuthenticationForm, 'extra_context': { 'title': 'Log in', 'year': datetime.now().year, } }
此代码定义三个属性:
template_name
标识 应用/login.html 文件中定义的“登录”页面的模板。 请记住,此链接是站点相对链接。 完整文件夹路径 app/templates/app/login.html。extra_context
向模板提供的默认上下文数据添加信息。 在这种情况下,信息包括“登录”标题以及日期、时间和年份。authentication_form
指定一个窗体类用于登录过程。 在模板中,此属性值显示为form
对象。 默认值为AuthenticationForm
(从django.contrib.auth.views
),但 Visual Studio 项目模板改用项目 应用/forms.py文件中定义的表单:from django import forms from django.contrib.auth.forms import AuthenticationForm from django.utils.translation import ugettext_lazy as _ class BootstrapAuthenticationForm(AuthenticationForm): """Authentication form which uses bootstrap CSS.""" username = forms.CharField(max_length=254, widget=forms.TextInput({ 'class': 'form-control', 'placeholder': 'User name'})) password = forms.CharField(label=_("Password"), widget=forms.PasswordInput({ 'class': 'form-control', 'placeholder':'Password'}))
表单类派生自
AuthenticationForm
,并专门替代用户名和密码字段以添加占位符文本。 Visual Studio 模板包含此显式代码,假设你可能想要自定义表单,例如添加密码强度验证。
当用户与应用进行交互并打开“登录”页面时,应用将呈现 login.html 模板。 变量
{{ form.username }}
和{{ form.password }}
呈现来自BootstrapAuthenticationForm
类的CharField
窗体。 还有一个内置部分,用于显示验证错误,如果你选择添加这些服务,则为社交登录提供现成的元素:{% extends "app/layout.html" %} {% block content %} <h2>{{ title }}</h2> <div class="row"> <div class="col-md-8"> <section id="loginForm"> <form action="." method="post" class="form-horizontal"> {% csrf_token %} <h4>Use a local account to log in.</h4> <hr /> <div class="form-group"> <label for="id_username" class="col-md-2 control-label">User name</label> <div class="col-md-10"> {{ form.username }} </div> </div> <div class="form-group"> <label for="id_password" class="col-md-2 control-label">Password</label> <div class="col-md-10"> {{ form.password }} </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="hidden" name="next" value="/" /> <input type="submit" value="Log in" class="btn btn-default" /> </div> </div> {% if form.errors %} <p class="validation-summary-errors">Please enter a correct user name and password.</p> {% endif %} </form> </section> </div> <div class="col-md-4"> <section id="socialLoginForm"></section> </div> </div> {% endblock %}
当用户在页面窗体中选择 登录 时,Django 会尝试对凭据进行身份验证,例如超级用户的凭据:
如果身份验证失败,用户将保留在“登录”页上,
form.errors
标记设置为 true:如果身份验证成功,Django 将在
next
字段中打开相对 URL,<input type="hidden" name="next" value="/" />
,在本例中为“主页”(/
)。
当应用在用户进行身份验证后呈现“主页”页面时,呈现 loginpartial.html 模板时,
user.is_authenticated
属性为 true。 在这种情况下,导航栏显示 Hello(用户名) 消息,注销 选项将替换 登录 选项:可以使用应用代码的其他部分中的
user.is_authenticated
属性来检查身份验证。
访问 Django 管理员接口
若要检查经过身份验证的用户是否有权访问特定资源,需要从数据库中检索特定于用户的权限。
特别是超级用户或管理员,有权使用网站相对 URL /admin/
和 /admin/doc/
访问内置的 Django 管理员接口。 有关详细信息,请参阅 使用 Django 身份验证系统(Django docs)。
若要启用对 Django 管理员接口的访问权限,请执行以下步骤:
将
docutils
Python 包安装到环境中。 请参阅 Python 环境包的安装说明。在 解决方案资源管理器中,展开 Django 项目文件夹,DjangoWeb/DjangoWeb/。 以下步骤更新此文件夹中的多个文件。
打开 Django 项目的 urls.py 文件并修改内容,如下所示:
在文件的顶部,将 URL 的以下包导入添加到当前列表的末尾:
from django.conf.urls import include
导入列表后,添加以下语句:
admin.autodiscover()
找到
urlpatterns
定义,并在'admin/'
项之前添加以下路径条目:path('admin/doc/', include('django.contrib.admindocs.urls')),
打开 Django 项目的 settings.py 文件,找到
INSTALLED_APPS
集合。 紧跟app
条目后添加以下条目:'django.contrib.admindocs',
停止并重启 Django Web 应用。
在浏览器的 URL 地址字段中,将应用的页面视图更改为
/admin/
或/admin/doc/
路由。 这些页面为超级用户提供对 Django 管理任务的访问权限,例如创建用户或组帐户、更改密码以及查看 Django 文档:
研究退出登录行为
超级用户可以通过两种方式注销和结束经过身份验证的会话。 Django Web 应用包括导航栏上的 注销 选项,Django 管理站点提供 注销 选项。
从 Django 管理站点退出登录
如果超级用户正在查看 Django 管理网站上的页面,则可以在网站导航栏上选择“注销”。 浏览器将刷新以显示网站的“退出登录”页面:
在此页上,用户有两个选项,主页,再次登录。 这两个选项均将用户返回到 Django 管理网站(/admin)的“主页”页面,提示用户重新输入其凭据。
从 Django Web 应用退出登录
如果超级用户正在 Django Web 应用中查看“关于”或“联系信息”等页面,则他们可以在 Django Web 应用导航栏中选择“退出登录”。 退出登录行为是最小的行为。 它只是结束经过身份验证的会话,并将用户浏览回应用“主页”。
可以重新设计注销行为,使其对用户更有信息价值。
在解决方案资源管理器 中,展开项目的 应用/模板/应用 文件夹,然后打开 loginpartial.html 文件。
在模板文件中,请注意,“注销”链接只是对站点相对 URL 路径“/login”(
href="{% url 'login' %}"
) 执行 HTTP POST (action="/logout" method="post"
) 操作。{% if user.is_authenticated %} <form id="logoutForm" action="/logout" method="post" class="navbar-right"> {% csrf_token %} <ul class="nav navbar-nav navbar-right"> <li><span class="navbar-brand">Hello {{ user.username }}!</span></li> <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li> </ul> </form> {% else %} <ul class="nav navbar-nav navbar-right"> <li><a href="{% url 'login' %}">Log in</a></li> </ul> {% endif %}
内置视图
django.contrib.auth.views.logout
函数处理此注销过程。当前行为并未显示任何 UI 来通知用户其已退出登录。 此过程只是根据 Django 项目的 URL 文件 (DjangoWeb/DjangoWeb/urls.py) 中定义的
'logout/'
路径模式将用户带回 Django Web 应用的“主页”页面:path('logout/', LogoutView.as_view(next_page='/'), name='logout'),
若要显示更丰富的注销确认信息,可以为应用创建“注销”页。
在 应用/模板/应用 文件夹中,创建名为 loggedoff.html的新 HTML 模板文件。
将以下内容添加到新模板文件:
{% extends "app/layout.html" %} {% block content %} <h3>You have been logged off</h3> {% endblock %}
在 Django 项目的 URL 文件中,DjangoWeb/DjangoWeb/urls.py更改
'logout/'
路径的 URL 模式,如下所示:path('logout/', LogoutView.as_view(template_name='app/loggedoff.html'), name='logout'),
更新的代码将添加一个
template_name
属性,以便与“已注销”页的新 HTML 模板配合使用。停止并重启 Django Web 应用。 再次登录,然后选择“退出登录”。 这一次,应用向用户显示一条信息性更丰富的消息,以确认他们已注销:
停止服务器并关闭应用程序浏览器窗口。
将项目保存到版本控制系统
如果你在本教程系列的整个过程中将 Visual Studio 解决方案提交到源代码控制,现在是进行一次新的提交的好时机。 按照本教程系列中的步骤 2(提交对源代码管理所做的更改)中的说明操作。
解决方案应与 GitHub 上的教程源代码匹配:Microsoft/python-sample-vs-learning-django。
在窗体元素中使用 {% csrf_token %} 标记
{% csrf_token %}
标记包含 Django 的内置跨网站请求伪造 (csrf) 保护(Django 文档)。 通常将此标记添加到涉及 POST、PUT 或 DELETE 请求方法(如窗体)的任何元素。 然后,模板呈现函数(render
)插入必要的保护。
教程评审
祝贺你完成 Visual Studio 中 Django 的本教程。
在本教程中,你将了解:
- 在 Visual Studio 中使用各种模板生成不同类型的 Django 项目
- 创建包含多个页面的 Django Web 应用
- 使用模板创建不同的路由和页面视图
- 提供静态文件、添加页面和使用模板继承
- 提供对受限应用页面和功能以及 Django 管理界面的经过身份验证的访问权限
相关内容
- Django 中的用户身份验证 (docs.djangoproject.com)
- GitHub 上的教程源代码(Microsoft/python-sample-vs-learning-django)