Django内置了授权的功能,我们可以快速使用。在本章中,我们将限制只有登录的用户才能访问各种页面。
改进CreateView
目前,新文章的作者可以被设置为任何用户。相反,它应该被自动设置为当前用户。默认的CreateView为我们提供了很多功能,但为了将当前用户设置为作者,我们需要对其进行定制。我们将从字段中删除作者,而通过form_valid方法自动设置。
articles/views.py
# articles/views.py
...
class ArticleCreateView(CreateView):
model = Article
template_name = 'article_new.html'
fields = ('title', 'body') # new
def form_valid(self, form): # new
form.instance.author = self.request.user
return super().form_valid(form)
...
现在创建文章不会再要求选择用户。
授权
退出登录再访问http://127.0.0.1:8000/articles/new/,创建news会失败:
Mixin
我们显然想设置一些授权,以便只有登录的用户才能访问该网站。我们可以使用mixin,这是一种特殊的多重继承,Django用它来避免重复的代码,并且仍然允许定制。例如,内置的通用ListView需要一种方法来返回模板。但DetailView和其他几乎所有的视图也是如此。Django没有在每个大的通用视图中重复相同的代码,而是将这一功能分解为名为TemplateResponseMixin的 "混合器"。ListView和DetailView都使用这个混合器来渲染合适的模板。
为了限制只有登录过的用户才能访问视图,Django有一个LoginRequired混合器,我们可以使用。它很强大,而且非常简明。
articles/views.py
# articles/views.py
from django.contrib.auth.mixins import LoginRequiredMixin # new
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from django.urls import reverse_lazy
from .models import Article
...
class ArticleCreateView(LoginRequiredMixin, CreateView): # new
...
现在如果不登录访问http://127.0.0.1:8000/articles/new/会直接跳转到登录页面。
UpdateView和DeleteView
编辑和删除视图: 任何登录的用户都可以对任何文章进行修改。我们想要的是限制这种权限,以便只有文章的作者有这种权限。
我们可以在每个视图中添加权限逻辑,但更优雅的解决方案是创建专门的mixin,具有特定功能的类,我们想在Django代码中重用。更好的是,Django提供了一个内置的混合器,UserPassesTestMixin,就是为了这个目的。
articles/views.py
from django.contrib.auth.mixins import (
LoginRequiredMixin,
UserPassesTestMixin # new
)
from django.views.generic import ListView, DetailView # new
from django.views.generic.edit import UpdateView, DeleteView, CreateView # new
from django.urls import reverse_lazy # new
from .models import Article
class ArticleListView(LoginRequiredMixin, ListView):
model = Article
template_name = 'article_list.html'
class ArticleDetailView(LoginRequiredMixin, DetailView): # new
model = Article
template_name = 'article_detail.html'
class ArticleUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView): # new
model = Article
fields = ('title', 'body',)
template_name = 'article_edit.html'
def test_func(self): # new
obj = self.get_object()
return obj.author == self.request.user
class ArticleDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView): # new
model = Article
template_name = 'article_delete.html'
success_url = reverse_lazy('article_list')
def test_func(self): # new
obj = self.get_object()
return obj.author == self.request.user
class ArticleCreateView(LoginRequiredMixin, CreateView): # new
model = Article
template_name = 'article_new.html'
fields = ('title', 'body') # new
def form_valid(self, form): # new
form.instance.author = self.request.user
return super().form_valid(form)
现在注销你的超级用户账户,用testuser登录。现在不能编辑或删除任何由你的超级用户写的帖子,会看到一个拒绝许可的403错误页面。
小结
我们的报纸应用程序几乎已经完成了。在这一点上,我们还可以采取进一步的措施,例如只向适当的用户显示编辑和删除链接,这将涉及到自定义模板标签,但总的来说,该应用程序处于良好状态。我们已经正确地配置了我们的文章,设置了权限和授权,用户认证也在有序进行。最后需要的项目是让其他登录的用户能够留下评论,我们将在下一章介绍。
网友评论