webentwicklung-frage-antwort-db.com.de

Übergeben Sie den Anforderungskontext von Viewset in Django Rest Framework an den Serializer

Ich habe einen Fall, in dem die Werte für ein Serialisierungsfeld von der Identität des aktuell angemeldeten Benutzers abhängen. Ich habe gesehen, wie der Benutzer beim Initialisieren eines Serialisierers zum Kontext hinzugefügt wird, aber ich bin mir nicht sicher, wie dies bei der Verwendung eines ViewSet geschieht, da Sie nur die Serialisiererklasse und nicht die tatsächliche Serialisiererinstanz angeben.

Grundsätzlich würde ich gerne wissen, wie es weitergeht:

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

zu:

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

Tut mir leid, wenn es aus den DOCs nicht klar war: Hinzufügen von zusätzlichem Kontext .__ 

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

Ich bin mir jedoch nicht sicher, wie ich das automatisch aus dem Viewset mache, da ich nur die Serialisiererklasse und nicht die Serialisiererinstanz selbst ändern kann.

42
oowowaee

GenericViewSet hat die get_serializer_context-Methode, die Sie überschreiben können:

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

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

Wenn Sie den übergeordneten Kontext in der überschriebenen Funktion get_serializer_context zurückgeben, wird der Zugriff auf die Anforderung und ihre Daten vereinfacht. 

 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

Dies ist sehr stabil, da jedes Mal, wenn wir Viewsets anfordern, auch Kontext zurückgegeben wird.

1
Shashank

verwenden Sie einfach get_serializer () in Ihren Viewsets

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)
0
steven.yan

die Werte für ein Serialisierungsfeld hängen von der Identität des aktuell angemeldeten Benutzers ab

So verarbeite ich solche Fälle in meinem ModelViewSet:

def perform_create(self, serializer):

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

    serializer.save()
0
ostergaard