Ich möchte einige Argumente von Viewset an die DRF Serializer-Klasse übergeben, daher habe ich 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')
Ansichten
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 dem Querystring von Ansichten an die Serializer-Klasse übergeben, und diese werden dann Feldern zugewiesen.
Diese Felder sind nicht in dynamisch erstellten Feldern enthalten.
Gleicher Fall in dieser Frage Stapelüberlauf , aber ich kann die Antwort nicht verstehen.
Kann mir jemand in diesem Fall helfen oder mir bessere Optionen vorschlagen.
python
django
rest
django-rest-framework
Shoaib Ijaz
quelle
quelle
get_serializer
Methode und überschreiben Sie sie, um eine benutzerdefinierte Instanz des Serializers zurückzugeben.Antworten:
Mit "context" arg für den "ModelSerializer" -Konstruktor ist das sehr einfach.
Zum Beispiel:
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 abzurufen.
Referenz
quelle
{'request': <rest_framework.request.Request object at 0x103a2ba20>, 'view': <api.views.CourseAssignmentViewSet object at 0x10326b828>, 'format': None}
Um die Antwort von Redcyb zu erfüllen, sollten Sie die
get_serializer_context
Methode aus Ihrer SichtGenericAPIView
wie folgt verwenden :def get_serializer_context(self): return {'user': self.request.user.email}
quelle
get_serializer_context
nicht aus, da der eigentliche Ort, an dem dervalidated_data
Kontext aktualisiert wirdserializer.save()
, die Methode ist, die vonViewSet.update() -> ViewSet.perform_update()
und aufgerufen wirdViewSet.create() -> ViewSet.perform_create()
. Aber der Haken ist, dass sie nicht**kwargs
mit dem Kontext weitergebensave()
. Um den Kontext zu mischen, müssen wir ihn überschreibenperform_create
und ihnperform_update
an übergebensave()
.In der YourView- Überschreibungsmethode können Sie Folgendes tun
get_serializer_context
:class YourView(GenericAPIView): def get_serializer_context(self): context = super().get_serializer_context() context["customer_id"] = self.kwargs['customer_id'] context["query_params"] = self.request.query_params return context
oder so:
class YourView(GenericAPIView): def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.context["customer_id"] = request.user.id serializer.context["query_params"] = request.query_params serializer.is_valid(raise_exception=True) ...
und überall in Ihrem Serializer können Sie es bekommen. Zum Beispiel in einer benutzerdefinierten Methode:
class YourSerializer(ModelSerializer): def get_alternate_name(self, obj): customer_id = self.context["customer_id"] query_params = self.context["query_params"] ...
quelle
Ein alter Code, den ich geschrieben habe und 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.
quelle
self.context['request'].query_params.get()
.