framework example ejemplo create django rest django-rest-framework

example - Marco Django REST: agregar campo adicional a ModelSerializer



django rest framework serializer (6)

Como Chemical Programer dijo en este comentario , en el último DRF puedes hacerlo así:

class FooSerializer(serializers.ModelSerializer): extra_field = serializers.SerializerMethodField() def get_extra_field(self, foo_instance): return foo_instance.a + foo_instance.b class Meta: model = Foo fields = (''extra_field'', ...)

http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

Quiero serializar un modelo, pero quiero incluir un campo adicional que requiera realizar algunas búsquedas en la base de datos en la instancia del modelo que se serializará:

class FooSerializer(serializers.ModelSerializer): my_field = ... # result of some database queries on the input Foo object class Meta: model = Foo fields = (''id'', ''name'', ''myfield'')

¿Cuál es la forma correcta de hacer esto? Veo que puede pasar un "contexto" adicional al serializador, ¿es la respuesta correcta para pasar en el campo adicional en un diccionario de contexto? Con ese enfoque, la lógica de obtener el campo que necesito no sería independiente con la definición del serializador, que es ideal ya que cada instancia serializada necesitará my_field . En otra parte de la documentación de los serializadores DRF, says "los campos adicionales pueden corresponder a cualquier propiedad o pueden llamarse en el modelo". ¿Hay campos adicionales de lo que estoy hablando? ¿Debería definir una función en la definición de modelo de Foo que devuelva my_field value, y en el serializador conecte my_field a ese callable? ¿Cómo se ve eso?

Gracias de antemano, feliz de aclarar la pregunta si es necesario.


Con la última versión de Django Rest Framework, debe crear un método en su modelo con el nombre del campo que desea agregar. No es necesario que @property y source=''field'' @property un error.

class Foo(models.Model): . . . def foo(self): return ''stuff'' . . . class FooSerializer(ModelSerializer): foo = serializers.ReadOnlyField() class Meta: model = Foo fields = (''foo'',)



Mi respuesta a una pregunta similar ( here ) podría ser útil.

Si tiene un Método de modelo definido de la siguiente manera:

class MyModel(models.Model): ... def model_method(self): return "some_calculated_result"

Puede agregar el resultado de llamar a dicho método a su serializador de la siguiente manera:

class MyModelSerializer(serializers.ModelSerializer): model_method_field = serializers.CharField(source=''model_method'')

ps Dado que el campo personalizado no es realmente un campo en su modelo, generalmente querrá que sea de solo lectura, así:

class Meta: model = MyModel read_only_fields = ( ''model_method_field'', )


Puede cambiar el método de su modelo a la propiedad y usarlo en el serializador con este enfoque.

class Foo(models.Model): . . . @property def my_field(self): return stuff . . . class FooSerializer(ModelSerializer): my_field = serializers.ReadOnlyField(source=''my_field'') class Meta: model = Foo fields = (''my_field'',)

Editar: con las versiones recientes de rest framework (probé 3.3.3), no es necesario cambiar a la propiedad. El método del modelo funcionará bien.


si desea leer y escribir en su campo adicional, puede usar un nuevo serializador personalizado, que amplía serializadores.Serializador, y úselo de esta manera

class ExtraFieldSerializer(serializers.Serializer): def to_representation(self, instance): # this would have the same as body as in a SerializerMethodField return ''my logic here'' def to_internal_value(self, data): return ''Any python object made with data: %s'' % data class MyModelSerializer(serializers.ModelSerializer): my_extra_field = ExtraFieldSerializer(source=''*'') class Meta: model = MyModel fields = [''id'', ''my_extra_field'']

Yo uso esto en campos anidados relacionados con alguna lógica personalizada