Python 用户账户(创建用户账户)

Web应用程序的核心是让任何用户都能够注册账户并能够使用它,不管用户身处何方。在本章中,你将创建一些表单,让用户能够添加主题和条目,以及编辑既有的
条目。你还将学习Django如何防范对基于表单的网页发起的常见攻击,这让你无需花太多时间考虑确保应用程序安全的问题。
然后,我们将实现一个用户身份验证系统。你将创建一个注册页面,供用户创建账户,并让有些页面只能供已登录的用户访问。接下来,我们将修改一些视图函数,
使得用户只能看到自己的数据。你将学习如何确保用户数据的安全。

创建用户账户

在这一节,我们将建立一个用户注册和身份验证系统,让用户能够注册账户,进而登录和注销。我们将创建一个新的应用程序,其中包含与处理用户账户相关的所有功能。我们
还将对模型Topic 稍做修改,让每个主题都归属于特定用户。

应用程序users

我们首先使用命令startapp 来创建一个名为users 的应用程序:

(ll_env)learning_log$ python manage.py startapp users
(ll_env)learning_log$ ls
❶ db.sqlite3 learning_log learning_logs ll_env manage.py users
(ll_env)learning_log$ ls users
❷ admin.py __init__.py migrations models.py tests.py views.py

这个命令新建一个名为users的目录(见❶),其结构与应用程序learning_logs 相同(见❷)。

将应用程序users 添加到settings.py中

在settings.py中,我们需要将这个新的应用程序添加到INSTALLED_APPS 中,如下所示:

--snip--
INSTALLED_APPS = (
--snip--
# 我的应用程序
'learning_logs',
'users',
) --snip--

这样,Django将把应用程序users 包含到项目中。

包含应用程序users 的URL

接下来,我们需要修改项目根目录中的urls.py,使其包含我们将为应用程序users 定义的URL:

from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^users/', include('users.urls', namespace='users')),
url(r'', include('learning_logs.urls', namespace='learning_logs')),
]

我们添加了一行代码,以包含应用程序users 中的文件urls.py。这行代码与任何以单词users打头的URL(如http://localhost:8000/users/login/)都匹配。我们还创建了命名空
间’users’ ,以便将应用程序learning_logs 的URL同应用程序users 的URL区分开来。

登录页面

我们首先来实现登录页面的功能。为此,我们将使用Django提供的默认登录视图,因此URL模式会稍有不同。在目录learning_log/users/中,新建一个名为urls.py的文件,并在其中添
加如下代码:

"""为应用程序users定义URL模式"""
from django.conf.urls import url
❶ from django.contrib.auth.views import login
from . import views
urlpatterns = [
# 登录页面
❷ url(r'^login/$', login, {'template_name': 'users/login.html'},
name='login'),
]

我们首先导入了默认视图login (见❶)。登录页面的URL模式与URL http://localhost:8000/users/login/匹配(见❷)。这个URL中的单词users让Django在users/urls.py中查找,而单词
login让它将请求发送给Django默认视图login (请注意,视图实参为login ,而不是views.login )。鉴于我们没有编写自己的视图函数,我们传递了一个字典,告诉Django
去哪里查找我们将编写的模板。这个模板包含在应用程序users 而不是learning_logs 中。

模板login.html

用户请求登录页面时,Django将使用其默认视图login ,但我们依然需要为这个页面提供模板。为此,在目录learning_log/users/中,创建一个名为templates的目录,并在其中创建一
个名为users的目录。以下是模板login.html,你应将其存储到目录learning_log/users/templates/users/中:

{% extends "learning_logs/base.html" %}
{% block content %}
❶ {% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
❷ <form method="post" action="{% url 'users:login' %}">
{% csrf_token %}
❸ {{ form.as_p }}
❹ <button name="submit">log in</button>
❺ <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}

这个模板继承了base.html,旨在确保登录页面的外观与网站的其他页面相同。请注意,一个应用程序中的模板可继承另一个应用程序中的模板。
如果表单的errors 属性被设置,我们就显示一条错误消息(见❶),指出输入的用户名—密码对与数据库中存储的任何用户名—密码对都不匹配。
我们要让登录视图处理表单,因此将实参action 设置为登录页面的URL(见❷)。登录视图将一个表单发送给模板,在模板中,我们显示这个表单(见❸)并添加一个提交按
钮(见❹)。在❺处,我们包含了一个隐藏的表单元素——‘next’ ,其中的实参value 告诉Django在用户成功登录后将其重定向到什么地方——在这里是主页。

链接到登录页面

下面在base.html中添加到登录页面的链接,让所有页面都包含它。用户已登录时,我们不想显示这个链接,因此将它嵌套在一个{% if %} 标签中:

<p>
<a href="{% url 'learning_logs:index' %}">Learning Log</a> -
<a href="{% url 'learning_logs:topics' %}">Topics</a> -
❶ {% if user.is_authenticated %}
❷ Hello, {{ user.username }}.
{% else %}
❸ <a href="{% url 'users:login' %}">log in</a>
{% endif %}
</p>
{% block content %}{% endblock content %}

在Django身份验证系统中,每个模板都可使用变量user ,这个变量有一个is_authenticated 属性:如果用户已登录,该属性将为True ,否则为False 。这让你能够向已
通过身份验证的用户显示一条消息,而向未通过身份验证的用户显示另一条消息。

在这里,我们向已登录的用户显示一条问候语(见❶)。对于已通过身份验证的用户,还设置了属性username ,我们使用这个属性来个性化问候语,让用户知道他已登录(见
❷)。在❸处,对于还未通过身份验证的用户,我们再显示一个到登录页面的链接。

使用登录页面

前面建立了一个用户账户,下面来登录一下,看看登录页面是否管用。请访问http://localhost:8000/admin/,如果你依然是以管理员的身份登录的,请在页眉上找到注销链接并单击
它。

注销后,访问http://localhost:8000/users/login/,你将看到类似于图19-4所示的登录页面。输入你在前面设置的用户名和密码,将进入页面index。。在这个主页的页眉中,显示了一条
个性化问候语,其中包含你的用户名。

注销

现在需要提供一个让用户注销的途径。我们不创建用于注销的页面,而让用户只需单击一个链接就能注销并返回到主页。为此,我们将为注销链接定义一个URL模式,编写一个
视图函数,并在base.html中添加一个注销链接。

注销URL

下面的代码为注销定义了URL模式,该模式与URL http://locallwst:8000/users/logout/匹配。修改后的users/urls.py如下:

--snip--
urlpatterns = [
# 登录页面
--snip--
# 注销
url(r'^logout/$', views.logout_view, name='logout'),
]

这个URL模式将请求发送给函数logout_view() 。这样给这个函数命名,旨在将其与我们将在其中调用的函数logout() 区分开来(请确保你修改的是users/urls.py,而不是
learning_log/ urls.py)。

视图函数logout_view()

函数logout_view() 很简单:只是导入Django函数logout() ,并调用它,再重定向到主页。请打开users/views.py,并输入下面的代码:

from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
❶ from django.contrib.auth import logout
def logout_view(request):
"""注销用户"""
❷ logout(request)
❸ return HttpResponseRedirect(reverse('learning_logs:index'))

我们从django.contrib.auth中导入了函数logout() (见❶)。在❷处,我们调用了函数logout() ,它要求将request 对象作为实参。然后,我们重定向到主页(见❸)。

链接到注销视图

现在我们需要添加一个注销链接。我们在base.html中添加这种链接,让每个页面都包含它;我们将它放在标签{% if user.is_authenticated %} 中,使得仅当用户登录后
才能看到它:

--snip—
{% if user.is_authenticated %}
Hello, {{ user.username }}.
<a href="{% url 'users:logout' %}">log out</a>
{% else %}
<a href="{% url 'users:login' %}">log in</a>
{% endif %}
--snip--

这里的重点是创建能够正确工作的网站,因此几乎没有设置任何样式。确定所需的功能都能正确运行后,我们将设置这个网站的样式,使
其看起来更专业。

image

注册页面

下面来创建一个让新用户能够注册的页面。我们将使用Django提供的表单UserCreationForm ,但编写自己的视图函数和模板。

注册页面的URL模式

下面的代码定义了注册页面的URL模式,它也包含在users/urls.py中:

--snip--
urlpatterns = [
# 登录页面
--snip--
# 注册页面
url(r'^register/$', views.register, name='register'),
]

这个模式与URL http://localhost:8000/users/register/匹配,并将请求发送给我们即将编写的函数register() 。

视图函数register()

在注册页面首次被请求时,视图函数register() 需要显示一个空的注册表单,并在用户提交填写好的注册表单时对其进行处理。如果注册成功,这个函数还需让用户自动登
录。请在users/views.py中添加如下代码:

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import UserCreationForm
def logout_view(request):
--snip--
def register(request):
"""注册新用户"""
if request.method != 'POST':
# 显示空的注册表单
❶ form = UserCreationForm()
else:
# 处理填写好的表单
❷ form = UserCreationForm(data=request.POST)
❸ if form.is_valid():
❹ new_user = form.save()
# 让用户自动登录,再重定向到主页
❺ authenticated_user = authenticate(username=new_user.username,
password=request.POST['password1'])
❻ login(request, authenticated_user)
❼ return HttpResponseRedirect(reverse('learning_logs:index'))
context = {'form': form}
return render(request, 'users/register.html', context)

我们首先导入了函数render() ,然后导入了函数login() 和authenticate() ,以便在用户正确地填写了注册信息时让其自动登录。我们还导入了默认表
单UserCreationForm 。在函数register() 中,我们检查要响应的是否是POST请求。如果不是,就创建一个UserCreationForm 实例,且不给它提供任何初始数据(见
❶)。

如果响应的是POST请求,我们就根据提交的数据创建一个UserCreationForm 实例(见❷),并检查这些数据是否有效:就这里而言,是用户名未包含非法字符,输入的两
个密码相同,以及用户没有试图做恶意的事情。

如果提交的数据有效,我们就调用表单的方法save() ,将用户名和密码的散列值保存到数据库中(见❹)。方法save() 返回新创建的用户对象,我们将其存储在new_user
中。

保存用户的信息后,我们让用户自动登录,这包含两个步骤。首先,我们调用authenticate() ,并将实参new_user.username 和密码传递给它(见❺)。用户注册时,
被要求输入密码两次;由于表单是有效的,我们知道输入的这两个密码是相同的,因此可以使用其中任何一个。在这里,我们从表单的POST数据中获取与键’password1’ 相关
联的值。如果用户名和密码无误,方法authenticate() 将返回一个通过了身份验证的用户对象,而我们将其存储在authenticated_user 中。接下来,我们调用函
数login() ,并将对象request 和authenticated_user 传递给它(见❻),这将为新用户创建有效的会话。最后,我们将用户重定向到主页(见❼),其页眉中显示了
一条个性化的问候语,让用户知道注册成功了。

注册模板

注册页面的模板与登录页面的模板类似,请务必将其保存到login.html所在的目录中:

{% extends "learning_logs/base.html" %}
{% block content %}
<form method="post" action="{% url 'users:register' %}">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">register</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}

这里也使用了方法as_p ,让Django在表单中正确地显示所有的字段,包括错误消息——如果用户没有正确地填写表单。

链接到注册页面

接下来,我们添加这样的代码,即在用户没有登录时显示到注册页面的链接:

--snip--
{% if user.is_authenticated %}
Hello, {{ user.username }}.
<a href="{% url 'users:logout' %}">log out</a>
{% else %}
<a href="{% url 'users:register' %}">register</a> -
<a href="{% url 'users:login' %}">log in</a>
{% endif %}
--snip--

现在,已登录的用户看到的是个性化的问候语和注销链接,而未登录的用户看到的是注册链接和登录链接。请尝试使用注册页面创建几个用户名各不相同的用户账户。
在下一节,我们将对一些页面进行限制,仅让已登录的用户访问它们,我们还将确保每个主题都属于特定用户。

注意  这里的注册系统允许用户创建任意数量的账户。有些系统要求用户确认其身份:发送一封确认邮件,用户回复后其账户才生效。通过这样做,系统生成的垃圾
账户将比这里使用的简单系统少。然而,学习创建应用程序时,完全可以像这里所做的那样,使用简单的用户注册系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/37858.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10-BST(二叉树)-建立二叉搜索树,并进行前中后遍历

题目 来源 3540. 二叉搜索树 - AcWing题库 思路 建立二叉搜索树&#xff08;注意传参时用到了引用&#xff0c;可以直接对root进行修改&#xff09;&#xff0c;同时进行递归遍历&#xff1b;遍历可以分前中后三种写&#xff0c;也可以用标志来代替合在一起。其余详见代码。…

无人机点对点技术要点分析!

一、技术架构 1. 网络拓扑 Ad-hoc网络&#xff1a;无人机动态组建自组织网络&#xff0c;节点自主协商路由&#xff0c;无需依赖地面基站。 混合架构&#xff1a;部分场景结合中心节点&#xff08;如指挥站&#xff09;与P2P网络&#xff0c;兼顾集中调度与分布式协同。 2.…

[极客大挑战 2019]Knife——3.20BUUCTF练习day4(2)

[极客大挑战 2019]Knife——3.20BUUCTF练习day4(2) 解题内容 在一个文件中输入以下内容&#xff0c;该文件是phtml文件&#xff08;HTML嵌套PHP代码&#xff0c;可以绕过很多限制&#xff09;但在本题中要先改文件名为2.gif然后抓包修改后缀名为phtml,因为只可以上传gif和jpg…

1、环境初始化--Linux安装dockerCE

主要安装环境ubuntu、centos、Windows 因某些原因&#xff0c;使用阿里镜像源&#xff1a; https://developer.aliyun.com/mirror/docker-ce?spma2c6h.13651102.0.0.4a451b11EjxMKe Ubuntu安装步骤&相应解释 sudo apt-get update 解释&#xff1a; 刷新软件源列表 该命…

什么是 BA ?BA怎么样?BA和BI是什么关系?

前几天有朋友在评论区提到了BA这个角色&#xff0c;具体是干什么的&#xff0c;我大概来说一下。 什么是BA BA 英文的全称是Business Analyst&#xff0c;从字面上意思就是商业分析师&#xff0c;做过商业智能BI项目的应该比较了解。实际上以我个人的经验&#xff0c;BA 的角…

第六:go 操作 redis-go

Redis 在项目开发中redis的使用也比较频繁&#xff0c;本文介绍了Go语言中go-redis库的基本使用。 Redis介绍 Redis是一个开源的内存数据库&#xff0c;Redis提供了多种不同类型的数据结构&#xff0c;很多业务场景下的问题都可以很自然地映射到这些数据结构上。除此之外&am…

UDS诊断、ECU刷写、自动化测试、车联网测试、DTC故障注入测试、坏境测试、可靠性测试、压力测试、性能测试等

每日直播时间&#xff1a;&#xff08;直播方式&#xff1a;腾讯会议&#xff09; 周一到周五&#xff1a;20&#xff1a;00-23&#xff1a;00 周六与周日&#xff1a;9&#xff1a;00-17&#xff1a;00 向进腾讯会议学习的&#xff0c;可以关注我并后台留言 直播内容&#xff…

AI大模型介绍

大模型介绍 大模型是指具有大规模参数和复杂计算结构的机器学习模型&#xff0c;通常由深度神经网络构建而成&#xff0c;拥有数十亿甚至数千亿个参数 开发大模型不是从0开始&#xff0c;是建立在已有的大模型基座模型上做开发&#xff0c;构建企业知识库&#xff08;向量数据库…

C++ 异常 【无敌详细版】

1. C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 1. 终止程序&#xff0c;如assert&#xff0c;缺陷&#xff1a;用户难以接受。如发生内存错误&#xff0c;除0错误时就会终止程序。 2. 返回错误码&#xff0c;缺陷&#xff1a;需要程序员自己去查找对应的错误。…

redis的典型应用 --缓存

Redis最主要的用途&#xff0c;分为三个方面&#xff1a; 1.存储数据&#xff08;内存数据库&#xff09; 2.缓存&#xff08;最常用&#xff09; 3.消息队列 缓存 (cache) 是计算机中的⼀个经典的概念。核⼼思路就是把⼀些常⽤的数据放到触⼿可及(访问速度更快)的地⽅&…

初始操作系统---Linux

目录 前言: 硬件层是软件层设计的基石(冯诺依曼体系结构): 冯诺依曼体系结构: 整个系统的运行效率 存储分级的概念 感性的理解数据的流动: 初始操作系统: 本质: 操作系统存在的必要性: 进程(系统里的任务): 操作系统创建进程的方式: 一些内容补充: 系统调用: 小结: 前…

<项目> 主从Reactor模型的高并发服务器

目录 Reactor 概念 分类 单Reactor单线程 单Reactor多线程 多Reactor多线程 项目介绍 项目规划 模块关系 实现 TimerWheel -- 时间轮定时器 定时器系统调用 时间轮设计 通用类型Any Buffer Socket Channel Poller EventLoop&#xff08;核心&#xff09; eventfd 设计思路 …

游戏引擎学习第173天

今天的总结和计划 今天我们将继续昨天和前几天的工作&#xff0c;基本上已经完成了字体支持的功能&#xff0c;我们成功地把字体功能加入了游戏中&#xff0c;包括字距调整等基本功能。然而&#xff0c;我觉得整体还没有完全完成&#xff0c;感觉还有一些地方没有完全打理好&a…

Linux安装go环境

安装一个lazydocker&#xff0c;根据文档需要先安装go环境 https://github.com/jesseduffield/lazydocker 官方文档解析 https://go.dev/doc/install 文档内容如下&#xff0c;一共三步 1.删除先前安装的go&#xff0c;解压下载的go压缩包到/usr/local目录 2.添加环境变量&…

React如何导入md5,把密码password进行md5加密

在 React 项目里对密码进行 MD5 加密&#xff0c;你可以借助 crypto-js 库&#xff0c;它提供了 MD5 加密功能。以下是详细步骤&#xff1a; 1. 安装 crypto-js 库 在项目根目录下&#xff0c;通过以下命令来安装 crypto-js &#xff1a; npm install crypto-js 2. 在 Reac…

【ES】Elasticsearch学习

文章目录 简单的安装 简单的安装 参考&#xff1a;https://blog.csdn.net/smilehappiness/article/details/118466378 官网&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/current/targz.html 下载&#xff1a;https://www.elastic.co/cn/downloads/e…

Cool Request:可以统计任意方法耗时

什么是Cool Request Cool Request是一个IDEA中的接口调试插件&#xff0c;除了可以发起基本的HTTP请求之外&#xff0c;还提供了强大的反射调用能力&#xff0c;可以绕过拦截器&#xff0c;这点广受网友的好评&#xff0c;当然伴随着还有Spring中对Scheduled注解的调用&#x…

dfs(二十二)78. 子集

78. 子集 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的 &#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],[1,2]…

什么是TCP,UDP,MQTT?

以下内容来源于抖音,作者织点代码,读者根据文章内容以及相应论文添加自己的理解进行注释。 计算机之间怎么通信? 彼此之间用网线连接在一起就可以了 但是这样子太麻烦了,成本太高,操作也麻烦 集线器 于是我们可以把线拧在一起 而拧在一起的这个设备,就是集线器 但集线…

计算机操作系统(三) 操作系统的特性、运行环境与核心功能(附带图谱更好对比理解))

计算机操作系统&#xff08;三&#xff09; 操作系统的特性、运行环境与核心功能 前言一、操作系统的基本特性1.1 并发1.2 共享1.3 虚拟1.4 异步 二、操作系统的运行环境2.1 硬件支持2.2 操作系统内核2.3 处理机的双重工作模式2.4 中断与异常 三、操作系统的主要功能3.1 处理机…