python - queryset - partial update django rest framework
Pase argumentos adicionales a la clase Serializer en Django Rest Framework (4)
Quiero pasar algunos argumentos a la clase de serializador DRF desde Viewset, por lo que he intentado esto:
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'')
Puntos de vista
class OneZeroViewSet(viewsets.ModelViewSet):
serializer_class = OneZeroSerializer(realpart=1)
#serializer_class = OneZeroSerializer
queryset = OneZero.objects.all()
Básicamente quiero pasar algún valor basado en la cadena de consulta de las vistas a la clase Serializer y luego estos se asignarán a los campos.
Estos campos no se incluyen en el modelo, de hecho, son campos creados dinámicamente.
El mismo caso en esta pregunta stackoverflow , pero no puedo entender la respuesta.
¿Alguien puede ayudarme en este caso o sugerirme mejores opciones?
Es muy fácil con arg "context" para el constructor "ModelSerializer".
Por ejemplo:
en vista:
my_objects = MyModelSerializer(
input_collection,
many=True,
context={''user_id'': request.user.id}
).data
en serializadores:
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
...
para que pueda usar "self.context" para obtener parámetros adicionales.
Necesitará en el método View override get_serializer_context
así:
def get_serializer_context(self):
return {"customer_id": self.kwargs[''customer_id'']}
y en cualquier parte del serializer
puedes obtenerlo:
customer_id = self.context["customer_id"]
Para cumplir la respuesta de redcyb, considere usar en su vista el método GenericAPIView
de GenericAPIView
, como este:
def get_serializer_context(self):
return {''user'': self.request.user.email}
Un código antiguo que escribí, que podría ser útil: hecho para filtrar el serializador anidado:
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'')
Cómo anular 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):
.....
Espero que esto ayude a las personas que buscan esto.