Django DetailView - 如何更改 get_object 以检查字段

Django DetailView - How to change the get_object to check a field

所以我想制作一个 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 没有任何对象,然后为什么我试图从中获取用户,它找不到任何数据。

DetailViewget_object 方法已经知道如何通过 slug 获取对象。无需复制此代码,只需调用 super().

然后您可以直接将用户与 self.request.user 进行比较 - 无需使用 get_object_or_404.

从数据库中重新获取用户

最后,您无法 return 来自 get_object 的响应,该方法旨在 return 对象。但是,您可以引发异常 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

基于 class 的视图中的一种常见方法是覆盖 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)