wake-up-neo.com

Django Rest Framework - Hinzufügen eines benutzerdefinierten Felds in ModelSerializer

Ich habe ein ModelSerializer erstellt und möchte ein benutzerdefiniertes Feld hinzufügen, das nicht Teil meines Modells ist.

Ich habe eine Beschreibung zum Hinzufügen zusätzlicher Felder gefunden hier und Folgendes versucht:

customField = CharField(source='my_field')

Wenn ich dieses Feld hinzufüge und meine Funktion validate() aufrufe, ist dieses Feld nicht Teil des Diktats attr. attr enthält alle angegebenen Modellfelder mit Ausnahme der zusätzlichen Felder. Ich kann also in meiner überschriebenen Validierung nicht auf dieses Feld zugreifen, oder?

Wenn ich dieses Feld wie folgt zur Feldliste hinzufüge:

class Meta:
    model = Account
    fields = ('myfield1', 'myfield2', 'customField')

dann erhalte ich eine Fehlermeldung, weil customField nicht Teil meines Modells ist - was richtig ist, weil ich es nur für diesen Serializer hinzufügen möchte.

Gibt es eine Möglichkeit, ein benutzerdefiniertes Feld hinzuzufügen?

77
Ron

Sie tun das Richtige, außer dass CharField (und die anderen typisierten Felder) für beschreibbare Felder sind.

In diesem Fall möchten Sie nur ein einfaches schreibgeschütztes Feld, verwenden Sie stattdessen einfach:

customField = Field(source='get_absolute_url')
54
Tom Christie

In der Tat gibt es eine Lösung, ohne das Modell überhaupt zu berühren. Sie können SerializerMethodField verwenden, um eine beliebige Methode an Ihren Serializer anzuschließen.

class FooSerializer(ModelSerializer):
    foo = serializers.SerializerMethodField()

    def get_foo(self, obj):
        return "Foo id: %i" % obj.pk
54
Idaho

... zur Verdeutlichung, wenn Sie eine Modellmethode wie folgt definiert haben:

class MyModel(models.Model):
    ...

    def model_method(self):
        return "some_calculated_result"

Sie können das Ergebnis des Aufrufs dieser Methode wie folgt zu Ihrem Serializer hinzufügen:

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

p.s. Da das benutzerdefinierte Feld in Ihrem Modell eigentlich kein Feld ist, sollten Sie es normalerweise schreibgeschützt machen, wie folgt:

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

hier antworte auf deine frage. Sie sollten Ihrem Modellkonto hinzufügen:

@property
def my_field(self):
    return None

jetzt können Sie verwenden:

customField = CharField(source='my_field')

quelle: https://stackoverflow.com/a/18396622/3220916

13
va-dev

Zeigen self.author.full_name, Bei Field ist ein Fehler aufgetreten. Es funktionierte mit ReadOnlyField:

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    author_name = ReadOnlyField(source="author.full_name")
    class Meta:
        model = Comment
        fields = ('url', 'content', 'author_name', 'author')
8

In der letzten Version von Django Rest Framework müssen Sie in Ihrem Modell eine Methode mit dem Namen des Felds erstellen, das Sie hinzufügen möchten.

class Foo(models.Model):
    . . .
    def foo(self):
        return 'stuff'
    . . .

class FooSerializer(ModelSerializer):
    foo = serializers.ReadOnlyField()

    class Meta:
        model = Foo
        fields = ('foo',)
6