Django Tutorial Part 8: User authentication and permissions
先决条件: | 完成所有以前的教学课题,最多包括 Django教程第7部分:会话框架。 |
---|---|
目的: | 了解如何设置和使用用户身份验证和权限。 |
概述
Django提供了一个认证和授权("权限")系统,该系统构建在上一个教程中讨论的会话框架之上,允许您验证用户凭据 并定义每个用户允许执行的操作。 该框架包括 Users
和 Groups
(一次向多个用户应用权限的通用方法)的内置模型,用于指定用户 可以执行用于登录用户的任务,表单和视图,以及用于限制内容的查看工具。
注意:根据Django,认证系统旨在非常通用,因此不提供其他Web认证系统中提供的一些功能。 一些常见问题的解决方案可用作第三方包。 例如,限制登录尝试和针对第三方的身份验证(例如OAuth)。
在本教程中,我们将向您介绍如何在 LocalLibrary 中启用用户身份验证, a>网站,创建您自己的登录和注销页面,为您的模型添加权限,以及控制对页面的访问。 我们将使用身份验证/权限来显示为用户和图书馆员借用的图书列表。
认证系统非常灵活,您可以从头开始构建您的URL,表单,视图和模板,只需调用提供的API登录用户即可。 但是,在本文中,我们将使用Django的"stock"认证视图和表单登录和注销页面。 我们仍然需要创建一些模板,但这很容易。
我们还将向您展示如何创建权限,并检查视图和模板中的登录状态和权限。
启用身份验证
当我们创建骨架网站(在教程2中)时,会自动启用身份验证,因此您无需在此时再执行任何操作。
注意:当我们使用 django-admin startproject
命令创建应用程序时,所有必要的配置都已完成。 当我们第一次调用 python manage.py migrate
时,创建了用户和模型权限的数据库表。
配置在项目文件( locallibrary / locallibrary / settings.py )的 INSTALLED_APPS
和 MIDDLEWARE
部分中设置,如下所示:
INSTALLED_APPS = [ ... 'django.contrib.auth', #Core authentication framework and its default models. 'django.contrib.contenttypes', #Django content type system (allows permissions to be associated with models). .... MIDDLEWARE = [ ... 'django.contrib.sessions.middleware.SessionMiddleware', #Manages sessions across requests ... 'django.contrib.auth.middleware.AuthenticationMiddleware', #Associates users with requests using sessions. ....
创建用户和组
当我们在教程4中查看 Django管理网站时,您已经创建了第一个用户(这是一个超级用户,使用命令 python manage创建)。
py createsuperuser)。 我们的超级用户已经通过身份验证并拥有所有权限,因此我们需要创建一个测试用户来代表一个正常的网站用户。 我们将使用管理网站创建我们的 locallibrary 组和网站登录,因为它是最快的方式之一。
注意:您也可以以编程方式创建用户,如下所示。 你必须这样做,例如,如果开发一个接口,允许用户创建自己的登录(你不应该给用户访问管理站点)。
from django.contrib.auth.models import User # Create user and save to the database user = User.objects.create_user('myusername', 'myemail@crazymail.com', 'mypassword') # Update fields and then save again user.first_name = 'John' user.last_name = 'Citizen' user.save()
下面我们先创建一个组,然后创建一个用户。 即使我们没有任何权限为我们的库成员添加,如果我们需要以后,它会更容易一次添加到组,而不是单独给每个成员。
启动开发服务器,并导航到本地网络浏览器中的管理网站( http://127.0.0.1:8000/ admin / )。 使用您的超级用户帐户的凭据登录到网站。 管理网站的顶层显示所有模型,按"django应用程序"排序。 在验证和授权部分中,您可以点击用户或网上论坛链接查看其现有记录。
; width:661px;">
首先让我们为库成员创建一个新的组。
- Click the Add button (next to Group) to create a new Group; enter the Name "Library Members" for the group.
- We don't need any permissions for the group, so just press SAVE (you will be taken to a list of groups).
现在让我们创建一个用户:
- Navigate back to the home page of the admin site
- Click the Add button next to Users to open the Add user dialog.
- Enter an appropriate Username and Password/Password confirmation for your test user
- Press SAVE to create the user.
The admin site will create the new user and immediately take you to a Change user screen where you can change your username and add information for the User model's optional fields. These fields include the first name, last name, email address, the users status and permissions (only the Active flag should be set). Further down you can specify the user's groups and permissions, and see important dates related to the user (e.g. their join date and last login date). - In the Groups section, select Library Member group from the list of Available groups, and then press the right-arrow between the boxes to move it into the Chosen groups box.
- We don't need to do anything else here, so just select SAVE again, to go to the list of users.
而已!。 现在你有一个"正常的库成员"帐户,你将能够用于测试(一旦我们实现了页面,使他们能够登录)。
注意:您应该尝试创建其他库成员用户。 另外,为图书馆员创建一个组,并向其添加一个用户!
设置您的身份验证视图
Django提供了几乎所有你需要创建的认证页面来处理登录,注销和密码管理"开箱即用"。 这包括一个url映射器,视图和表单,但它不包括模板 - 我们必须创建自己的!
在本节中,我们将介绍如何将默认系统集成到LocalLibrary网站并创建模板。 我们将它们放在主项目URL中。
注意:您不必使用任何此类代码,但很可能是您想要的,因为它使事情变得更容易。 如果您更改用户模型(高级主题!),您几乎肯定需要更改表单处理代码,但即使如此,您仍然可以使用股票视图功能。
请注意:在这种情况下,我们可以合理地将验证页(包括网址和模板)放入我们的目录应用程序中。 但是,如果我们有多个应用程序,最好分离出这种共享登录行为,并使其可用于整个网站,这是我们在这里显示的!
项目网址
将以下内容添加到项目urls.py文件( locallibrary / locallibrary / urls.py )文件的底部:
#Add Django site authentication urls (for login, logout, password management) urlpatterns += [ url('^accounts/', include('django.contrib.auth.urls')), ]
导航到 http://127.0.0.1:8000/accounts/ 网址(请注意尾部正斜杠 !)和Django将显示一个错误,它找不到这个URL,并列出了所有的URL。 从中可以看到可以工作的网址,例如:
^accounts/ ^login/$ [name='login'] ^accounts/ ^logout/$ [name='logout'] ^accounts/ ^password_change/$ [name='password_change'] ^accounts/ ^password_change/done/$ [name='password_change_done'] ^accounts/ ^password_reset/$ [name='password_reset'] ^accounts/ ^password_reset/done/$ [name='password_reset_done'] ^accounts/ ^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm'] ^accounts/ ^reset/done/$ [name='password_reset_complete']
Exception Type: TemplateDoesNotExist Exception Value: registration/login.html
下一步是在搜索路径上创建注册目录,然后添加 login.html 文件。
模板目录
我们刚才添加的url(和隐式视图)希望在模板搜索路径中的某个位置的 / registration / 目录中找到它们相关的模板。 对于此网站,我们会将模板放置在 templates / registration / 目录中(即将模板放置在最上层目录 和 locallibrary 文件夹) - 请立即创建模板和注册目录。
要使这些目录对模板加载器可见(即将此目录放在模板搜索路径中),请打开项目设置( /locallibrary/locallibrary/settings.py ),然后更新 TEMPLATES
部分的\'DIRS\'
行,如图所示。
TEMPLATES = [ { ... 'DIRS': ['./templates',], 'APP_DIRS': True, ...
登录模板
重要:本文中提供的身份验证模板是Django演示登录模板的非常基本/稍微修改的版本。 您可能需要自定义它们为您自己使用!
创建一个名为/ locallibrary / templates / registration / login.html 的新HTML文件。 给它以下内容:
{% extends "base_generic.html" %} {% block content %} {% if form.errors %} <p>Your username and password didn't match. Please try again.</p> {% endif %} {% if next %} {% if user.is_authenticated %} <p>Your account doesn't have access to this page. To proceed, please login with an account that has access.</p> {% else %} <p>Please login to see this page.</p> {% endif %} {% endif %} <form method="post" action="{% url 'login' %}"> {% csrf_token %} <div> <td>{{ form.username.label_tag }}</td> <td>{{ form.username }}</td> </div> <div> <td>{{ form.password.label_tag }}</td> <td>{{ form.password }}</td> </div> <div> <input type="submit" value="login" /> <input type="hidden" name="next" value="" /> </div> </form> {# Assumes you setup the password_reset view in your URLconf #} <p><a href="{% url 'password_reset' %}">Lost password?</a></p> {% endblock %}
此模板与我们之前看到的模板有一些相似之处 - 它扩展了我们的基本模板,并覆盖了 content
块。 其余的代码是相当标准的表单处理代码,我们将在后面的教程中讨论。 您现在需要知道的是,这将显示一个窗体,您可以在其中输入您的用户名和密码,如果您输入无效的值,将提示您在页面刷新时输入正确的值。
返回登录页面( http://127.0.0.1:8000/accounts/login/ >),一旦您保存了模板,您应该看到这样:
; width:441px;">
如果您尝试登录将成功,您将被重定向到另一个页面(默认情况下,这将是 http ://127.0.0.1:8000 / accounts / profile / )。 这里的问题是,默认情况下Django期望在登录后,你会想要到一个配置文件页面,这可能是或不是这种情况。 由于您尚未定义此网页,因此您会收到另一个错误讯息!
打开项目设置( /locallibrary/locallibrary/settings.py ),然后将下面的文字添加到底部。 现在,当您登录时,您应该被重定向到网站主页默认情况下。
# Redirect to home URL after login (Default redirects to /accounts/profile/) LOGIN_REDIRECT_URL = '/'
注销模板
如果您导航到注销网址( http://127.0.0.1:8000/accounts/logout/ a>),那么您会看到一些奇怪的行为 - 您的用户将被确实注销,但您会转到管理注销页面。 这不是你想要的,如果只是因为该页面上的登录链接会转到管理员登录屏幕(只有拥有 is_staff
权限的用户才能使用)。
创建并打开/ locallibrary / templates / registration / logged_out.html 。 在下面的文本中复制:
{% extends "base_generic.html" %} {% block content %} <p>Logged out!</p> <a href="{% url 'login'%}">Click here to login again.</a> {% endblock %}
这个模板很简单。 它只是显示一条消息,通知您已注销,并提供一个链接,您可以按返回登录屏幕。 如果再次访问注销URL,您应该会看到此页面:
; width:385px;">
密码重置模板
默认密码重置系统使用电子邮件向用户发送重置链接。 您需要创建表单以获取用户的电子邮件地址,发送电子邮件,允许他们输入新密码,并在整个过程完成时注意。
以下模板可用作起点。
Password reset form
这是用于获取用户的电子邮件地址(用于发送密码重置电子邮件)的表单。 创建 /locallibrary/templates/registration/password_reset_form.html ,并提供以下内容:
{% extends "base_generic.html" %} {% block content %} <form action="" method="post">{% csrf_token %} {% if form.email.errors %} {{ form.email.errors }} {% endif %} <p>{{ form.email }}</p> <input type="submit" class="btn btn-default btn-lg" value="Reset password" /> </form> {% endblock %}
Password reset done
此表单在您的电子邮件地址收集后显示。 创建 /locallibrary/templates/registration/password_reset_done.html ,并提供以下内容:
{% extends "base_generic.html" %} {% block content %} <p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p> {% endblock %}
Password reset email
此模板提供了我们将发送给用户的HTML电子邮件的文本,其中包含重置链接。 创建 /locallibrary/templates/registration/password_reset_email.html ,并提供以下内容:
Someone asked for password reset for email {{ email }}. Follow the link below: {{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
Password reset confirm
此页面是您在单击密码重置电子邮件中的链接后输入新密码的位置。 创建 /locallibrary/templates/registration/password_reset_confirm.html ,并提供以下内容:
{% extends "base_generic.html" %} {% block content %} {% if validlink %} <p>Please enter (and confirm) your new password.</p> <form action="" method="post"> <div style="display:none"> <input type="hidden" value="{{ csrf_token }}" name="csrfmiddlewaretoken"> </div> <table> <tr> <td>{{ form.new_password1.errors }} <label for="id_new_password1">New password:</label></td> <td>{{ form.new_password1 }}</td> </tr> <tr> <td>{{ form.new_password2.errors }} <label for="id_new_password2">Confirm password:</label></td> <td>{{ form.new_password2 }}</td> </tr> <tr> <td></td> <td><input type="submit" value="Change my password" /></td> </tr> </table> </form> {% else %} <h1>Password reset failed</h1> <p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p> {% endif %} {% endblock %}
Password reset complete
这是最后一个密码重置模板,显示该模板以在密码重置成功时通知您。 创建 /locallibrary/templates/registration/password_reset_complete.html ,并提供以下内容:
{% extends "base_generic.html" %} {% block content %} <h1>The password has been changed!</h1> <p><a href="{% url 'login' %}">log in again?</a></p> {% endblock %}
测试新的身份验证页面
现在您已添加了网址配置并创建了所有这些模板,验证页面现在应该可以正常工作了!
您可以尝试使用以下网址登录并注销超级用户帐户,以测试新的身份验证页:
您可以从登录页面的链接中测试密码重置功能。 请注意,Django只会向已存储在其数据库中的地址(用户)发送重置电子邮件!
注意:密码重置系统要求您的网站支持电子邮件,这超出了本文的范围,因此此部分无法使用。 要允许测试,请将以下行放在settings.py文件的末尾。 这会记录发送到控制台的任何电子邮件(因此您可以从控制台复制密码重置链接)。
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
有关详细信息,请参见发送电子邮件(Django docs)。
针对经过身份验证的用户进行测试
本节讨论我们可以做什么来根据用户是否登录来选择性地控制用户看到的内容。
在模板中测试
您可以使用 {{user}}
模板变量获取模板中当前登录用户的信息(当我们在我们的骨架中设置项目时,默认将其添加到模板上下文中 )。
通常,您将首先针对 {{user.is_authenticated}}
模板变量进行测试,以确定用户是否有资格查看特定内容。 为了演示这一点,接下来我们将更新侧边栏,如果用户已注销则显示"登录"链接,如果他们已登录,则显示"注销"链接。
打开基本模板( /locallibrary/catalog/templates/base_generic.html ),然后将以下文本复制到 sidebar
块中紧挨 endblock
>模板标签。
<ul class="sidebar-nav"> ... {% if user.is_authenticated %} <li>User: {{ user.get_username }}</li> <li><a href="{% url 'logout'%}?next={{request.path}}">Logout</a></li> {% else %} <li><a href="{% url 'login'%}?next={{request.path}}">Login</a></li> {% endif %} </ul>
如您所见,我们使用 if
- else
- endif
模板标签有条件地显示文本,基于 {{user.is_authenticated
}} 为true。 如果用户通过身份验证,我们知道我们有一个有效的用户,因此我们调用 {{user.get_username}} 来显示他们的名字。
我们使用 url
模板标记和相应网址配置的名称创建登录和注销链接网址。 还要注意我们如何在URL的末尾附加?next = {{request.path}}
。 此操作是添加包含当前页面的地址(URL)的下一步 ,到链接的URL的结尾。 在用户成功登录/注销后,视图将使用此" next
"值将用户重定向到他们首次单击登录/注销链接的页面。
注意:尝试一下! 如果您在主页上,并单击侧边栏中的登录/注销,则操作完成后,您应该返回到同一页面。
视图中的测试
如果使用基于函数的视图,限制对函数的访问的最简单的方法是将 login_required
装饰器应用于视图函数,如下所示。 如果用户登录,那么您的视图代码将正常执行。 如果用户未登录,则将重定向到项目设置( settings.LOGIN_URL
)中定义的登录URL,将当前绝对路径作为 next
URL参数传递 。 如果用户成功登录,则他们将返回此页面,但这次被验证。
from django.contrib.auth.decorators import login_required @login_required def my_view(request): ...
注意:您可以通过在 request.user.is_authenticated
上测试手动完成相同类型的事情,但装饰器更方便!
同样,在基于类的视图中限制对已登录用户的访问的最简单方法是从 LoginRequiredMixin
派生。 您需要在超类列表中,在主视图类之前首先声明此混合。
from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): ...
这具有与 login_required
装饰器完全相同的重定向行为。 您还可以指定用户重定向的替代位置(如果未通过身份验证( login_url
)和URL参数名称而不是" next
"以插入当前绝对 路径( redirect_field_name
)。
class MyView(LoginRequiredMixin, View): login_url = '/login/' redirect_field_name = 'redirect_to'
有关其他详细信息,请查看 > Django docs here 。
示例 - 列出当前用户的图书
现在我们知道如何将页面限制为特定用户,让我们创建当前用户借用的书籍的视图。
不幸的是,我们还没有办法让用户借书! 因此,在我们创建书籍列表之前,我们首先扩展 BookInstance
模型,以支持借用的概念,并使用Django Admin应用程序将一些书籍借给我们的测试用户。
楷模
首先,我们必须让用户有一个 BookInstance
(我们已经有一个状态
和 due_back
日期 ,但是我们还没有在这个模型和用户之间有任何关联,我们将使用 ForeignKey
(一对多)字段创建一个,我们还需要一个简单的机制来测试 一本借来的书已经逾期了。
打开 catalog / models.py ,然后从 django.contrib.auth.models
中导入 User
在文件的顶部,因此 User
可用于使用它的后续代码):
from django.contrib.auth.models import User
接下来将 borrower
字段添加到 BookInstance
模型中:
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
当我们在这里时,我们添加一个属性,我们可以从我们的模板调用,以告诉特定的书实例是否过期。 虽然我们可以在模板本身计算,使用如下所示的属性将更加高效。
from datetime import date @property def is_overdue(self): if date.today() > self.due_back: return True return False
现在我们更新了模型,我们需要对项目进行新的迁移,然后应用这些迁移:
python3 manage.py makemigrations python3 manage.py migrate
管理员
现在打开 catalog / admin.py ,并将 borrower
字段添加到 list_display
中的 BookInstanceAdmin
fieldsets
,如下所示。 这将使该字段在管理员部分中可见,以便我们可以在需要时将 User
分配给 BookInstance
。
@admin.register(BookInstance) class BookInstanceAdmin(admin.ModelAdmin): list_display = ('book', 'status', 'borrower', 'due_back', 'id') list_filter = ('status', 'due_back') fieldsets = ( (None, { 'fields': ('book','imprint', 'id') }), ('Availability', { 'fields': ('status', 'due_back','borrower',) }), )
贷了几本书
现在,它可以借书给特定的用户,去借出一些 BookInstance
记录(设置他们的借用
字段给你的测试用户,使 状态"贷款"并在未来和过去设置到期日。
注意:我们不会拼写此过程,因为您已经知道如何使用管理网站!
在贷款视图
现在,我们将添加一个视图,以获取已借给当前用户的所有图书的列表。 我们将使用我们熟悉的相同的通用基于类的列表视图,但是这次我们还将从 LoginRequiredMixin
导入和派生,以便只有已登录的用户可以调用此视图。 我们还将选择声明一个 template_name
,而不是使用默认值,因为我们最终可能会有一些不同的BookInstance记录列表,以及不同的视图和模板。
将以下内容添加到catalog / views.py中:
from django.contrib.auth.mixins import LoginRequiredMixin class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): """ Generic class-based view listing books on loan to current user. """ model = BookInstance template_name ='catalog/bookinstance_list_borrowed_user.html' paginate_by = 10 def get_queryset(self): return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')
为了将我们的查询限制为当前用户的BookInstance对象,我们如上所示重新实现 get_queryset()
。 请注意,"o"是"借出"的存储代码,我们通过 due_back
日期排序,以便先显示最早的项目。
贷款簿的URL conf
现在打开 /catalog/urls.py ,并添加一个指向上述视图的 url()
(您只需将下面的文本复制到文件末尾即可)。
urlpatterns += [ url(r'^mybooks/$', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'), ]
贷款书的模板
现在我们需要为这个页面做的是添加一个模板。 首先,创建模板文件 /catalog/templates/catalog/bookinstance_list_borrowed_user.html ,并提供以下内容:
{% extends "base_generic.html" %} {% block content %} <h1>Borrowed books</h1> {% if bookinstance_list %} <ul> {% for bookinst in bookinstance_list %} <li class="{% if bookinst.is_overdue %}text-danger{% endif %}"> <a href="{% url 'book-detail' bookinst.book.pk %}">{{bookinst.book.title}}</a> ({{ bookinst.due_back }}) </li> {% endfor %} </ul> {% else %} <p>There are no books borrowed.</p> {% endif %} {% endblock %}
此模板非常类似于之前为 Book
和 Author
对象创建的模板。 这里唯一的"新"是我们检查在模型(bookinst.is_overdue
)中添加的方法,并使用它来改变过期项目的颜色。
当开发服务器运行时,您现在应该可以在浏览器中查看登录用户的列表, > http://127.0.0.1:8000/catalog/mybooks/ 。 尝试这与您的用户登录并注销(在第二种情况下,您应该被重定向到登录页面)。
将列表添加到侧栏
最后一步是将这个新页面的链接添加到侧边栏。 我们将把它放在我们显示已登录用户的其他信息的同一部分。
打开基本模板( /locallibrary/catalog/templates/base_generic.html ),然后将粗线添加到侧边栏,如图所示。
<ul class="sidebar-nav"> {% if user.is_authenticated %} <li>User: {{ user.get_username }}</li> <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li> <li><a href="{% url 'logout'%}?next={{request.path}}">Logout</a></li> {% else %} <li><a href="{% url 'login'%}?next={{request.path}}">Login</a></li> {% endif %} </ul>
它是什么样子的?
当任何用户登录时,他们会在侧边栏中看到我的借阅链接,并且显示的书籍列表如下(第一本书没有到期日,这是我们希望的错误 在后面的教程中修复!)。
; width:530px;">
权限
权限与模型相关联,并定义具有权限的用户可以在模型实例上执行的操作。 默认情况下,Django会自动为所有模型提供添加,更改和权限,允许具有相关权限的用户通过 管理网站。 您可以为模型定义自己的权限,并将其授予特定用户。 您还可以更改与同一模型的不同实例关联的权限。
测试视图和模板中的权限非常类似,用于测试身份验证状态(实际上,测试权限也会测试身份验证)。
楷模
使用 permissions
字段在模型" class Meta
"中定义权限。 您可以在元组中指定任意数量的权限,每个权限本身在包含权限名称和权限显示值的嵌套元组中定义。 例如,我们可以定义一个权限,以允许用户标记图书已返回,如图所示:
class BookInstance(models.Model): ... class Meta: ... permissions = (("can_mark_returned", "Set book as returned"),)
然后,我们可以将权限分配给管理网站中的"图书管理员"组。
打开 catalog / models.py ,然后添加如上所示的权限。 您需要重新运行迁移(调用 python3 manage.py makemigrations
和 python3 manage.py migrate
)以适当地更新数据库。
模板
当前用户的权限存储在名为 {{perms}}
的模板变量中。 您可以使用相关联的Django"应用"中的特定变量名称来检查当前用户是否具有特定权限。 如果用户具有此权限,则 {{perms.catalog.can_mark_returned}}
将为 True
,否则为 False
。 我们通常使用模板 {%if%}
来测试权限,如下所示:
{% if perms.catalog.can_mark_returned
%}
<!-- We can mark a BookInstance as returned. -->
<!-- Perhaps add code to link to a "book return" view here. -->
{% endif %}
视图
权限可以在函数视图中使用 permission_required
装饰器或在基于类的视图中使用 PermissionRequiredMixin
来测试。 模式和行为与登录身份验证相同,但当然您可能需要添加多个权限。
函数视图装饰器:
from django.contrib.auth.decorators import permission_required @permission_required('catalog.can_mark_returned
') @permission_required('catalog.can_edit
') def my_view(request): ...
基于类的视图的权限所需的混合。
from django.contrib.auth.mixins import PermissionRequiredMixin class MyView(PermissionRequiredMixin, View): permission_required = 'catalog.can_mark_returned
' # Or multiple of permissions: permission_required = ('catalog.can_mark_returned
', 'catalog.can_edit')
例子
我们不会在此更新 LocalLibrary ; 也许在下一个教程!
挑战自己
在本文前面,我们向您展示了如何为当前用户创建一个页面,列出他们借用的书籍。 现在的挑战是创建一个类似的页面,该页面仅对图书馆员可见,显示已借用的所有图书,其中包括每位借款人的姓名。
您应该能够遵循与其他视图相同的模式。 主要区别是,您需要将视图限制为只有图书馆员。 您可以根据用户是否是工作人员(函数装饰: staff_member_required
,模板变量: user.is_staff
)来执行此操作,但建议您改用 > can_mark_returned
权限和 PermissionRequiredMixin
,如上一节所述。
重要:记住不要使用超级用户进行基于权限的测试(即使尚未定义权限,权限检查也始终对超级用户返回true)。 而是创建库管理器用户,并添加所需的功能。
完成后,您的网页应该如下面的屏幕截图所示。
; width:500px;">
概要
优秀的工作 - 你现在创建了一个网站,图书馆成员可以登录并查看自己的内容,图书馆员(具有正确的权限)可以使用查看所有借出的图书和他们的借款人。 目前我们仍然只是查看内容,但是当您想要开始修改和添加数据时,使用相同的原理和技术。
在下一篇文章中,我们将讨论如何使用Django表单收集用户输入,然后开始修改一些存储的数据。
也可以看看
- User authentication in Django (Django docs)
- Using the (default) Django authentication system (Django docs)
- Introduction to class-based views > Decorating class-based views (Django docs)