web-dev-qa-db-ja.com

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にあるオブジェクトのスラッグを言う必要があるときにのみ 'slug'と表示されます。これから、object_instanceにはオブジェクトがありません。そのため、ユーザーをそこから取得しようとすると、データが見つかりません。

7
Alex Haines

DetailViewの_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)
_
20
Alasdair