web-dev-qa-db-fra.com

Django Rest Framework - Comment ajouter un champ personnalisé dans ModelSerializer

J'ai créé un ModelSerializer et je souhaite ajouter un champ personnalisé qui ne fait pas partie de mon modèle.

J'ai trouvé une description pour ajouter des champs supplémentaires ici et j'ai essayé ce qui suit:

customField = CharField(source='my_field')

Lorsque j'ajoute ce champ et appelle ma fonction validate(), ce champ ne fait pas partie du attr dict. attr contient tous les champs du modèle spécifiés, à l'exception des champs supplémentaires. Donc, je ne peux pas accéder à ce champ dans ma validation écrasée, puis-je?

Quand j'ajoute ce champ à la liste de champs comme ceci:

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

alors j'obtiens une erreur parce que customField ne fait pas partie de mon modèle - ce qui est correct car je veux l'ajouter uniquement pour ce sérialiseur.

Est-il possible d'ajouter un champ personnalisé?

77
Ron

Vous faites ce qu'il faut, sauf que CharField (et les autres champs typés) sont réservés aux champs inscriptibles.

Dans ce cas, vous voulez juste un simple champ en lecture seule, utilisez plutôt:

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

En fait il y a une solution sans toucher du tout le modèle. Vous pouvez utiliser SerializerMethodField qui vous permet de connecter n'importe quelle méthode à votre sérialiseur.

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

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

... pour plus de clarté, si vous définissez une méthode de modèle de la manière suivante:

class MyModel(models.Model):
    ...

    def model_method(self):
        return "some_calculated_result"

Vous pouvez ajouter le résultat de l'appel de cette méthode à votre sérialiseur de la manière suivante:

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

p.s. Comme le champ personnalisé n'est pas vraiment un champ dans votre modèle, vous souhaiterez généralement le rendre en lecture seule, comme suit:

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

répondre ici pour votre question. vous devriez ajouter à votre compte modèle:

@property
def my_field(self):
    return None

maintenant vous pouvez utiliser:

customField = CharField(source='my_field')

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

13
va-dev

Montrer self.author.full_name, J'ai eu une erreur avec Field. Cela a fonctionné avec ReadOnlyField:

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

Avec la dernière version de Django Rest Framework, vous devez créer une méthode dans votre modèle avec le nom du champ que vous souhaitez ajouter.

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

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

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