2

私が想像しているのは非常に一般的なシナリオですが、検索で明確な解決策が見つかりませんでした。

ほとんどのオブジェクトがユーザーとの FK 関係を持っている Web アプリがあります。これらのオブジェクトについて、関連するユーザーが self.request.user と同じであることを確認したいと思います。

get_object をオーバーライドして、オブジェクトを返す前にこの単純なチェックを実行する mixin を作成しました。

より良い方法はありますか?ここでは、たとえば 404 を上げます。実際のコードでは、おそらくこれに特化したメッセージを返します。

class CheckObjectUserMixin(object):
    def get_object(self, queryset=None):
        if queryset is None:
            queryset = self.get_queryset()

        pk = self.kwargs.get(self.pk_url_kwarg, None)
        slug = self.kwargs.get(self.slug_url_kwarg, None)
        if pk is not None:
            queryset = queryset.filter(pk=pk)

        elif slug is not None:
            slug_field = self.get_slug_field()
            queryset = queryset.filter(**{slug_field: slug})

        else:
            raise AttributeError(u"Generic detail view %s must be called with "
                                 u"either an object pk or a slug."
                                 % self.__class__.__name__)

        try:
            obj = queryset.get()
        except ObjectDoesNotExist:
            raise Http404(_(u"No %(verbose_name)s found matching the query") %
                          {'verbose_name': queryset.model._meta.verbose_name})

        # Until here it was the code from Django's get_object.
        # Now for the CheckObjectUserMixin I perform a simple check. 
        # If the object does not belong to the request user, we want to raise an 404.

        if obj.user_id != self.request.user.id:
            raise Http404(_(u'You do not have permission to view this page'))
        else:
            return obj
4

1 に答える 1

3

get_objectあなたのコードは正しいと思いますが、Django のコードをすべてコピーする必要はありません。代わりに、次のようにすることができます。

from django.views.generic.detail import SingleObjectMixin

class CheckObjectUserMixin(SingleObjectMixin):
    def get_object(self, queryset=None):
        obj = super(CheckObjectUserMixin, self).get_object(queryset)
        if obj.user_id != self.request.user.id:
            raise Http404
        return obj
于 2012-09-18T09:28:47.477 に答える