Django DetailView - Как изменить get_object для проверки поля

Поэтому я хочу сделать 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() но когда я его печатаю, он говорит "слизняк", только когда слизень должен сказать слаг-объект, который находится в URL. Исходя из этого, object_instance не имеет никакого объекта, а затем, почему я пытаюсь получить от него пользователя, он не может найти никаких данных.

1 ответ

Решение

DetailView"s get_object Метод уже знает, как получить объект слизняком. Там нет необходимости дублировать этот код, просто позвоните 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)
Другие вопросы по тегам