ModelSerializer utilisant la propriété de modèle

95

J'essaie de sérialiser un modèle contenant un champ de propriété que je souhaite également sérialiser.

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

Lorsque j'essaye d'accéder à l'URL associée, j'obtiens une exception de sérialiseur (KeyError) sur la ext_linkpropriété.

Comment puis-je sérialiser la ext_linkpropriété?

Sander Smits
la source

Réponses:

135

Comme ce n'est pas un champ de modèle, il doit être ajouté explicitement à la classe de sérialiseur

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

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')
Tom Christie
la source
5
Une remarque : la liste des champs dans Meta est facultative. Si vous omettezfields, dans l'exemple ci-dessus, vous obtiendrez tous lesMyModelchamps plusext_linkdans les données sérialisées. Et c'est vraiment génial pour les modèles complexes! EDIT : Au moins, c'est vrai pourdjangorestframework==2.3.14.
e.thompsy
Pour moi, l'utilisation de sérialiseurs.Field a donné une erreur. "serializers.ReadOnlyField" fonctionne si to_representation n'est pas défini et que la vue est en lecture seule.
Shashank Singla
13
J'utilise 3.3.x et ajouter simplement des propriétés aux champs n'est pas suffisant. Je dois encore ajouter explicitement via ext_link = serializers.ReadOnlyField ().
jarmod
4
en utilisant DRF 3.4.6 sur Python 3.5.1 et Django 1.10, l'ajout de champs fonctionne très bien.
Vaibhav Mishra
9
Remarque: en utilisant, fields = "__all__"j'ai également dû ajouter myfield = serializers.ReadOnlyField()comme jarmod spécifié, en utilisant la version 3.7.7
Robert Townley
20

comme @Robert Townleycommentaire, cela fonctionne avec la version 3.8.2:

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

    class Meta:
        model = MyModel
        fields = "__all__"
suhailvs
la source