web-dev-qa-db-ja.com

Django Rest Frameworkでビューセットからシリアライザーに要求コンテキストを渡します

シリアライザーフィールドの値が、現在ログインしているユーザーのIDに依存する場合があります。シリアライザーを初期化するときにコンテキストにユーザーを追加する方法を見てきましたが、実際のシリアライザーインスタンスではなくシリアライザークラスのみを提供するため、ViewSetを使用するときにこれを行う方法がわかりません。

基本的に私はどのように行くのか知りたいです:

class myModelViewSet(ModelViewSet):
   queryset = myModel.objects.all()
   permission_classes = [DjangoModelPermissions]
   serializer_class = myModelSerializer

に:

class myModelSerializer(serializers.ModelSerializer):
    uploaded_by = serializers.SerializerMethodField()
    special_field = serializers.SerializerMethodField()

    class Meta:
        model = myModel

    def get_special_field(self, obj):
        if self.context['request'].user.has_perm('something.add_something'):
           return something

DOCから明確でない場合は申し訳ありません。 Adding Extra Context

serializer = AccountSerializer(account, context={'request': request})
serializer.data

しかし、シリアライザインスタンス自体ではなく、シリアライザクラスのみを変更できるため、ビューセットから自動的にそれを行う方法がわかりません。

49
oowowaee

GenericViewSetにはget_serializer_contextオーバーライドできるメソッド:

class myModelViewSet(ModelViewSet):
    queryset = myModel.objects.all()
    permission_classes = [DjangoModelPermissions]
    serializer_class = myModelSerializer

    def get_serializer_context(self):
        return {'request': self.request}
71
Syslo

オーバーライドされた関数get_serializer_contextで親コンテキストを返すと、リクエストとそのデータに簡単にアクセスできます。

 class myModelViewSet(ModelViewSet):
       queryset = myModel.objects.all()
       permission_classes = [DjangoModelPermissions]
       serializer_class = myModelSerializer

       def get_serializer_context(self):
       """
       pass request attribute to serializer
       """
           context = super(myModelViewSet, self).get_serializer_context()
           return context

ビューセットを要求するたびにコンテキストも返すため、これは非常に安定しています。

1
Shashank

ビューセットでget_serializer()を使用するだけです

def get_serializer(self, *args, **kwargs):
    """
    Return the serializer instance that should be used for validating and
    deserializing input, and for serializing output.
    """
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()
    return serializer_class(*args, **kwargs)
1
steven.yan

シリアライザーフィールドの値は、現在ログインしているユーザーのIDに依存します

ModelViewSetでこのようなケースを処理する方法は次のとおりです。

def perform_create(self, serializer):

    user = self.request.user
    if user.username == 'myuser':
        serializer.data['myfield'] = 'something'

    serializer.save()
0
ostergaard