So I want to make a DetailView
that shows a photo by itself and its associated information. However, I want to have it make sure the user has permission to access the photo as well.
This is the urls.py for the view
url(r'^photo/(?P<slug>[\-\d\w]+)/$', views.PhotoDetail.as_view(), name='photo'),
This is the 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
As you can see I try to get_slug_field()
but when I print it it only says 'slug' when the slug should say the objects slug which is in the url.
From this the object_instance doesn't have any object and then why I try to get the user from it, it can't find any data.
The DetailView
's get_object
method already knows how to fetch an object by the slug. There's no need to duplicate this code, just call super()
.
Then you can compare the user to self.request.user
directly - there's no need to refetch the user from the database with get_object_or_404
.
Finally, you can't return a response from get_object
, the method is meant to return the object. You can however raise an exception like 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
A common approach in class based views is to override get_queryset
and filter by user. The get_object
method will use this queryset when fetching the object. If the object is not in the queryset, then the user will get a 404 error.
class PhotoDetail(DetailView):
def get_queryset(self):
queryset = super(PhotoDetail, self).get_queryset()
return queryset.filter(photoextended__user=self.request.user)