Django Web
身份验证系统搭建(下)
接上一篇实现用户功能,完善数据库模型。
接上一节,这次我们需要创建一个新的应用程序,其中包含与处理用户账户相关的所有功能。还需要对模型稍加修改,让每个主题都归属于特定用户。
创建用户账户
创建
首先,使用 startapp
来创建一个名为 users
的应用程序:
1 | python3 manage.py startapp users |
添加到 settings.py
中
这样,Django
将把应用程序 users
包含到项目中。
创建应用程序 users
的 URL
首先,在项目层路由中(根目录的urls.py
)设计 users
的 URL
:
1 | from django.contrib import admin |
然后,新建应用层(users
)的 urls.py
,同样,在之后的页面路由中负责转发应用程序 users
的函数方法到视图层。
登录页面
设计应用层的 URL
1 | from django.urls import path, include |
注意,和之前不同的是,这一次我们没有设计视图层,而是将请求发送给 Django
的默认视图函数 LoginView
,函数参数指明登录模板的位置。
模板
在应用 users
下的路径建立模板: users
=> templates
=> users
=> login.html
login.html
:
1 |
|
链接到登录页面
更改首页 index.html
,链接到 login.html
:
1 |
|
这时,可以使用管理员用户进行登录尝试,访问http://127.0.0.1:8000/users/login/
进入登录页面。
注销
现在需要提供一个让用户注销的途径,我们不用创建用于注销的页面,而是让用户单击一个链接完成注销并返回到主页。
为此,需要为链接定义一个 URL
模式,编写一个视图函数,并在首页 index.html
添加一个注销链接。
注销 URL
1 | from django.urls import path, include |
视图函数 logout_view
views.py
:
1 | from django.shortcuts import render |
链接到注销视图
在主页添加链接:
index.html
:
1 |
|
注册页面
接下来就是创建一个让新用户可以注册的页面,我们使用
Django
提供的表单UserCreationForm
。
URL
模式
1 | from django.urls import path, include |
视图函数 register()
views.py
:
1 | from django.http import HttpResponseRedirect |
注册模板
模板路径:users
=> templates
=> users
=> register.html
register.html
:
1 |
|
链接到注册页面
index.html
:
1 |
|
让用户拥有自己的数据
用户应该能够输入其专有的数据,因此我们将创建一个系统,确定各项数据所属的用户,再限制对页面的访问,让用户只能使用自己的数据。
我们需要修改模型 Topic
,让每个主题都归属于特定用户。这也将影响条目,因为每个条目都属于特定的主题。
首先,限制对一些页面的访问。
使用 @login_required
限制访问
Django
提供了装饰器@login_required
,可以实现对于某些页面,只允许已经登录的用户访问它们。
- 限制对
topics
页面的访问
只允许已登录的用户请求 topics
页面:
learning_logs/views.py
:
1 | --snip-- |
login_required()
的代码检查用户是否已登录,仅当用户已登录时, Django
才会运行 get_topics_page()
的代码;如果用户未登录,就重定向到登录页面。
为实现这种重定向,我们需要修改 setting.py
,让 Django
知道哪里去找登录页面:
在 setting.py
末尾添加:
1 | LOGIN_URL = '/users/login/' |
- 全面限制对项目的访问
除主页(get_index_page()
、注册页面(register()
)和注销页面(logout_view()
),限制其他所有视图函数的页面访问。
将数据关联到用户
现在,需要将数据关联到提交它们的用户。我们只需将最高层的数据关联到用户,这样更低层的数据会自动关联到用户。
下面来修改模型 Topic
,在其中添加一个关联到用户的外键。这样以后,必须对数据库进行迁移,最后,对必要的视图进行修改,使其只显示与当前登录用户相关联的数据。
- 修改模型
toopic
只涉及两行:
1 | from django.db import models |
导入模型 User
,建立外键关系。
- 确定当前有哪些用户
- 迁移数据库
知道用户 ID
之后,就可以迁移数据库了。
1 | python3 manage.py makemigrations learning_logs |
这里我们将既有的所有主题关联到了管理用户 akashi
上(通过 ID
),接下来使用这个值来迁移数据库:
1 | python3 manage.py migrate |
只允许用户访问自己的主题
当前,无论以哪一个用户身份登录,都可以看到所有的主题。现在,我们来改变这种情况,只向用户显示属于自己的主题。
在 views.py
中,对函数 get_topics_page()
做如下修改:
1 |
|
保护用户的主题
现在,我们还没有对显示单个主题的页面访问进行限制,可以通过 URL
对不是当前用户的主题进行查看。
为修复这种问题,我们在视图函数 get_entry_page()
获取请求的条目前进行检查:
1 | from django.http import HttpResponseRedirect, Http404 |
保护页面 edit_entry
使用同样的方法,禁止用户通过 URL
来访问其他用户的条目:
1 |
|
将新主题关联到当前用户
当前,用于添加新主题的页面存在问题,因为它没有将新主题关联到特定的用户。
以下修复问题:
1 |
|
设置项目样式
第三方应用程序 django-bootstrap3
我们使用 django-bootstrap3
来将 Bootstrap
继承到项目中。这个应用程序下载必要的 Bootstrap
文件,将它们存放到项目的合适位置,让我们可以在项目的模板中使用样式设置指令。
为安装 django-bootstrap3
,在活动的虚拟环境中执行如下命令:
1 | pip3 install django-bootstrap3 |
接下来,需要在 settings.py
中的 INSTALLED_APPS
中添加如下代码,在项目中包含应用程序 django-bootstrap3
:
1 | INSTALLED_APPS = [ |
主页样式 index
1 | {% load bootstrap3 %} |
话题页样式 topics
1 | {% load bootstrap3 %} |
条目页样式 topic
1 | {% load bootstrap3 %} |
新建话题 new_topic
1 | {% load bootstrap3 %} |
新建条目 new_entry
1 | {% load bootstrap3 %} |
编辑条目 edit_entry
1 | {% load bootstrap3 %} |
注册 register
1 | {% load bootstrap3 %} |
登录 login
1 | {% load bootstrap3 %} |