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é?
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')
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
... 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',
)
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')
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')
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',)