ModelSerializer verwendet die Modelleigenschaft

93

Ich versuche, ein Modell zu serialisieren, das ein Eigenschaftsfeld enthält, das ich auch serialisieren möchte.

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

Beim Versuch, zur zugehörigen URL zu gelangen, wird eine Serializer-Ausnahme (KeyError) für die ext_linkEigenschaft angezeigt .

Wie kann ich die ext_linkEigenschaft serialisieren ?

Sander Smits
quelle

Antworten:

131

Da es sich nicht um ein Modellfeld handelt, muss es explizit zur Serializer-Klasse hinzugefügt werden

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

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')
Tom Christie
quelle
5
Ein Hinweis : Die Feldliste in Meta ist optional. Wenn Siefieldsim obigen Beispielweglassen, erhalten Sie alleMyModelFelder plusext_linkin den serialisierten Daten. Und das ist wirklich großartig für komplexe Modelle! EDIT : Zumindest gilt dies fürdjangorestframework==2.3.14.
e.thompsy
Für mich hat die Verwendung von Serializern.Field einen Fehler gegeben. "serializers.ReadOnlyField" funktioniert, wenn to_representation nicht definiert und die Ansicht schreibgeschützt ist.
Shashank Singla
13
Ich verwende 3.3.x und das einfache Hinzufügen von Eigenschaften zu Feldern reicht nicht aus. Ich muss noch explizit über ext_link = serializers.ReadOnlyField () hinzufügen.
Jarmod
4
Wenn Sie DRF 3.4.6 unter Python 3.5.1 und Django 1.10 verwenden, funktioniert das Hinzufügen zu Feldern einwandfrei.
Vaibhav Mishra
9
Hinweis: Mit fields = "__all__"Ich musste auch myfield = serializers.ReadOnlyField()als Jarmod angegeben hinzufügen , mit Version 3.7.7
Robert Townley
18

als @Robert TownleyKommentar funktioniert diese mit Version 3.8.2:

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

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