Django DetailView - 如何更改 get_object 以检查字段
Posted
技术标签:
【中文标题】Django DetailView - 如何更改 get_object 以检查字段【英文标题】:Django DetailView - How to change the get_object to check a field 【发布时间】:2017-07-27 22:35:07 【问题描述】:所以我想制作一个DetailView
,它可以单独显示一张照片及其相关信息。但是,我想让它确保用户也有权访问照片。
这是视图的 urls.py
url(r'^photo/(?P<slug>[\-\d\w]+)/$', views.PhotoDetail.as_view(), name='photo'),
这是views.py
class PhotoDetail(DetailView):
template_name = 'otologue/photo_detail.html'
def get_object(self, queryset=None):
slug = self.get_slug_field()
print(slug)
object_instance = Photo.objects.filter(slug=slug)
print(object_instance)
object_user = object_instance.photoextended.user
user = get_object_or_404(User, username=self.request.user) # Get the user in the view
if object_user != user: # See if the object_user is the same as the user
return HttpResponseForbidden('Permission Error')
else:
return object_instance
如您所见,我尝试使用get_slug_field()
,但是当我打印它时,它只会说“slug”,而 slug 应该说是 url 中的对象 slug。
由此 object_instance 没有任何对象,然后为什么我试图从中获取用户,它找不到任何数据。
【问题讨论】:
请注意,filter()
返回照片的查询集。如果你想要一张照片,你想要Photo.objects.get(slug=slug)
(尽管这可能会引发get_object_or_404
。
【参考方案1】:
DetailView
的 get_object
方法已经知道如何通过 slug 获取对象。无需重复此代码,只需调用super()
。
然后您可以直接将用户与self.request.user
进行比较 - 无需使用get_object_or_404
从数据库中重新获取用户。
最后,您不能从get_object
返回响应,该方法旨在返回对象。但是,您可以引发 Http404
之类的异常。
from django.http import Http404
class PhotoDetail(DetailView):
def get_object(self, queryset=None):
obj = super(PhotoDetail, self).get_object(queryset=queryset)
if obj.user != obj.photoextended.user:
raise Http404()
return obj
基于类的视图中的一种常见方法是覆盖get_queryset
并按用户过滤。 get_object
方法将在获取对象时使用此查询集。如果对象不在查询集中,则用户将收到 404 错误。
class PhotoDetail(DetailView):
def get_queryset(self):
queryset = super(PhotoDetail, self).get_queryset()
return queryset.filter(photoextended__user=self.request.user)
【讨论】:
感谢您的出色回答似乎完美无缺。我把它改成这个,因为它想要一个查询集 'class PhotoDetail(DetailView): template_name = 'otologue/photo_detail.html' queryset = Photo.objects def get_queryset(self): queryset = super(PhotoDetail, self).get_queryset() return queryset.filter(photoextended__user=self.request.user)' 它如何设法获得正确的照片对象似乎令人困惑。查询集是否会自动查找查询结果中的 slug 并与 url 中的 slugfield 进行比较get_object
方法从来自get_queryset
的查询集开始,并使用来自 URL 的 slug 进行过滤以获取对象。您可能会发现 ccbv 有助于探索基于类的视图中的方法如何组合在一起。以上是关于Django DetailView - 如何更改 get_object 以检查字段的主要内容,如果未能解决你的问题,请参考以下文章
Django Generic Views:教程中,DetailView如何自动提供变量?
Django - DetailView 中的 DateTimeField
如何使用当前登录用户作为 Django DetailView 的 PK?
当指定的对象不存在时,如何从 Django DetailView 重定向?