web-dev-qa-db-ja.com

Django Rest Framework-ModelSerializerでカスタムフィールドを追加する方法

ModelSerializerを作成し、モデルの一部ではないカスタムフィールドを追加します。

追加フィールド here を追加する説明を見つけて、次のことを試しました。

_customField = CharField(source='my_field')
_

このフィールドを追加してvalidate()関数を呼び出すと、このフィールドはattr dictの一部ではありません。 attrには、追加のフィールドを除く、指定されたすべてのモデルフィールドが含まれます。上書きされた検証でこのフィールドにアクセスできませんか?

このフィールドを次のようにフィールドリストに追加すると:

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

customFieldは私のモデルの一部ではないため、エラーが発生します。このシリアライザーのためだけに追加したいので正しいことです。

カスタムフィールドを追加する方法はありますか?

77
Ron

CharField(および他の入力フィールド)が書き込み可能なフィールドであることを除いて、あなたは正しいことをしています。

この場合、単純な読み取り専用フィールドが必要なので、代わりに次を使用します。

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

実際、すべてのモデルに触れることなく解決策があります。 SerializerMethodFieldを使用して、任意のメソッドをシリアライザーにプラグインできます。

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

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

...わかりやすくするために、次の方法で定義されたモデルメソッドがある場合:

class MyModel(models.Model):
    ...

    def model_method(self):
        return "some_calculated_result"

次のようにして、上記のメソッドを呼び出した結果をシリアライザーに追加できます。

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

追伸カスタムフィールドは実際にはモデル内のフィールドではないため、通常は次のように読み取り専用にする必要があります。

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

あなたの質問に答えてください。モデルアカウントに追加する必要があります。

@property
def my_field(self):
    return None

使用できるようになりました:

customField = CharField(source='my_field')

ソース: https://stackoverflow.com/a/18396622/3220916

13
va-dev

self.author.full_nameを表示するには、Fieldでエラーが発生しました。 ReadOnlyFieldで動作しました:

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

Django Rest Frameworkの最後のバージョンでは、追加するフィールドの名前を使用してモデルにメソッドを作成する必要があります。

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

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

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