ModelSerializer usando propriedade de modelo

95

Estou tentando serializar um modelo que contém um campo de propriedade que também desejo serializar.

models.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')

Ao tentar obter o URL relacionado, recebo uma exceção do serializador (KeyError) na ext_linkpropriedade.

Como posso serializar a ext_linkpropriedade?

Sander Smits
fonte

Respostas:

134

Por não ser um campo de modelo, ele precisa ser adicionado explicitamente à classe do serializador

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

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')
Tom Christie
fonte
5
Uma observação : a lista de campos em Meta é opcional. Se você omitirfields, no exemplo acima, obterá todos osMyModelcampos maisext_linkos dados serializados. E isso é realmente incrível para modelos complexos! EDIT : Pelo menos, isso é verdade paradjangorestframework==2.3.14.
e.thompsy
Para mim, usando serializadores.Field deu um erro. "serializers.ReadOnlyField" funcionará se to_representation não estiver definido e a visualização for somente leitura.
Shashank Singla de
13
Estou usando 3.3.xe simplesmente adicionar propriedades aos campos não é suficiente. Ainda preciso adicionar explicitamente via ext_link = serializers.ReadOnlyField ().
jarmod
4
usando DRF 3.4.6 no Python 3.5.1 e Django 1.10, adicionar aos campos funciona bem.
Vaibhav Mishra
9
Nota: Usando fields = "__all__"eu também tive que adicionar myfield = serializers.ReadOnlyField()como jarmod especificado, usando a versão 3.7.7
Robert Townley
20

como @Robert Townleycomentário de, funciona com a versão 3.8.2:

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

    class Meta:
        model = MyModel
        fields = "__all__"
Suhailvs
fonte