wake-up-neo.com

Übergeben Sie zusätzliche Argumente an die Serializer-Klasse in Django Rest Framework

Ich möchte einige Argumente von Viewset an die DRF-Serializer-Klasse übergeben. Ich habe Folgendes versucht:

class OneZeroSerializer(rest_serializer.ModelSerializer):

    def __init__(self, *args, **kwargs):
        print args # show values that passed

    location = rest_serializer.SerializerMethodField('get_alternate_name')

    def get_alternate_name(self, obj):
        return ''


    class Meta:
        model = OneZero

        fields = ('id', 'location')

Aufrufe

class OneZeroViewSet(viewsets.ModelViewSet):

   serializer_class = OneZeroSerializer(realpart=1)
   #serializer_class = OneZeroSerializer

   queryset = OneZero.objects.all()

Grundsätzlich möchte ich einen Wert basierend auf der Abfragezeichenfolge von Ansichten an die Serializer-Klasse übergeben, und diese werden dann Feldern zugewiesen.

Diese Felder sind in Model nicht enthalten, sondern dynamisch erstellte Felder.

Gleicher Fall bei dieser Frage stackoverflow , aber ich kann die Antwort nicht verstehen.

Kann mir jemand in diesem Fall weiterhelfen oder mir bessere Möglichkeiten vorschlagen.

55
Shoaib Ijaz

Es ist sehr einfach mit "context" arg für den "ModelSerializer" -Konstruktor.

Beispielsweise:

im Hinblick auf:

my_objects = MyModelSerializer(
    input_collection, 
    many=True, 
    context={'user_id': request.user.id}
).data

in Serialisierern:

class MyModelSerializer(serializers.ModelSerializer):
...

    is_my_object = serializers.SerializerMethodField('_is_my_find')
...

    def _is_my_find(self, obj):
        user_id = self.context.get("user_id")
        if user_id:
            return user_id in obj.my_objects.values_list("user_id", flat=True)
        return False
...

sie können also "self.context" verwenden, um zusätzliche Parameter zu erhalten.

Referenz

77
redcyb

Um die Antwort von redcyb zu erfüllen, sollten Sie aus Ihrer Sicht das get_serializer_context Methode aus GenericAPIView, wie folgt:

def get_serializer_context(self):
    return {'user': self.request.user.email}
20
andilabs

Sie müssen in der View override get_serializer_context -Methode wie folgt vorgehen:

def get_serializer_context(self):
    return {"customer_id": self.kwargs['customer_id']}

und irgendwo in der serializer können Sie es bekommen:

customer_id = self.context["customer_id"]
16
M.Void

Ein alter Code, den ich geschrieben habe, der hilfreich sein könnte, um verschachtelte Serializer zu filtern:

class MySerializer(serializers.ModelSerializer):

    field3  = serializers.SerializerMethodField('get_filtered_data')

    def get_filtered_data(self, obj):
        param_value = self.context['request'].QUERY_PARAMS.get('Param_name', None)
        if param_value is not None:
            try:
                data = Other_model.objects.get(pk_field=obj, filter_field=param_value)
            except:
                return None
            serializer = OtherSerializer(data)
            return serializer.data
        else:
            print "Error stuff"

    class Meta:
        model = Model_name
        fields = ('filed1', 'field2', 'field3')

So überschreiben Sie get_serializer_class:

class ViewName(generics.ListAPIView):

    def get_serializer_class(self):
        param_value = self.context['request'].QUERY_PARAMS.get('Param_name', None)
        if param_value is not None:
            return Serializer1
        else:
            return Serializer2

    def get_queryset(self):
       .....

Hoffe das hilft Leuten die danach suchen.

7
yeaske