ModelSerializer usando la propiedad del modelo

95

Estoy tratando de serializar un modelo que contiene un campo de propiedad que también quiero serializar.

modelos.py:

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    slug = models.AutoSlugField(populate_from='name')

    @property
    def ext_link(self):
        return "/".join([settings.EXT_BASE_URL, self.slug])

serializers.py:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')

Cuando intento acceder a la URL relacionada, obtengo una excepción de serializador (KeyError) en la ext_linkpropiedad.

¿Cómo puedo serializar la ext_linkpropiedad?

Sander Smits
fuente

Respuestas:

134

Debido a que no es un campo de modelo, debe agregarse explícitamente a la clase de serializador

class MyModelSerializer(serializers.ModelSerializer):
    ext_link = serializers.Field()

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')
Tom Christie
fuente
5
Una nota : la lista de campos en Meta es opcional. Si omitefields, en el ejemplo anterior, obtendría todos losMyModelcampos másext_linken los datos serializados. ¡Y esto es realmente asombroso para modelos complejos! EDITAR : Al menos, esto es cierto paradjangorestframework==2.3.14.
e.thompsy
Para mí, el uso de serializadores. Field dio un error. "serializers.ReadOnlyField" funciona si to_representation no está definido y la vista es de solo lectura.
Shashank Singla
13
Estoy usando 3.3.xy simplemente agregar propiedades a los campos no es suficiente. Todavía tengo que agregar explícitamente a través de ext_link = serializers.ReadOnlyField ().
jarmod
4
usando DRF 3.4.6 en Python 3.5.1 y Django 1.10, agregar campos funciona bien.
Vaibhav Mishra
9
Nota: Usando fields = "__all__"también tuve que agregar myfield = serializers.ReadOnlyField()como jarmod especificado, usando la versión 3.7.7
Robert Townley
20

como @Robert Townleyel comentario de, esto funciona con la versión 3.8.2:

class MyModelSerializer(serializers.ModelSerializer):
    ext_link = serializers.ReadOnlyField()

    class Meta:
        model = MyModel
        fields = "__all__"
suhailvs
fuente