100

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

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

customField = CharField(source='my_field')

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

このフィールドを次のようにフィールドリストに追加すると、次のようになります。

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

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

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

4

8 に答える 8

93

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

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

    def get_foo(self, obj):
        return "Foo id: %i" % obj.pk
于 2016-09-14T11:14:58.737 に答える
66

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

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

customField = Field(source='get_absolute_url')
于 2013-01-29T13:38:57.120 に答える
18

...わかりやすくするために、モデルメソッドを次のように定義している場合:

class MyModel(models.Model):
    ...

    def model_method(self):
        return "some_calculated_result"

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

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

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

class Meta:
    model = MyModel
    read_only_fields = (
        'model_method_field',
        )
于 2015-04-06T16:56:44.430 に答える
14

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

@property
def my_field(self):
    return None

今、あなたは使うことができます:

customField = CharField(source='my_field')

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

于 2014-01-21T22:21:10.690 に答える
12

表示するため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')
于 2016-09-02T05:29:42.120 に答える
7

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

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

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

    class Meta:
        model = Foo
        fields = ('foo',)
于 2016-06-30T14:21:48.557 に答える
6

モデルシリアライザーに書き込み可能なカスタムフィールドを追加するためのソリューションを探していました。私はこれを見つけましたが、この質問への回答ではカバーされていません。

確かに、独自の単純なシリアライザーを作成する必要があるようです。

class PassThroughSerializer(serializers.Field):
    def to_representation(self, instance):
        # This function is for the direction: Instance -> Dict
        # If you only need this, use a ReadOnlyField, or SerializerField
        return None

    def to_internal_value(self, data):
        # This function is for the direction: Dict -> Instance
        # Here you can manipulate the data if you need to.
        return data

これで、このシリアライザーを使用して、ModelSerializerにカスタムフィールドを追加できます。

class MyModelSerializer(serializers.ModelSerializer)
    my_custom_field = PassThroughSerializer()

    def create(self, validated_data):
        # now the key 'my_custom_field' is available in validated_data
        ...
        return instance

これは、モデルMyModelに実際に呼び出されたプロパティmy_custom_fieldがあるが、そのバリデーターを無視したい場合にも機能します。

于 2019-10-07T17:05:40.310 に答える
6

ここですべての答えを読んだ後、私の結論は、これをきれいに行うことは不可能であるということです。ダーティで遊んで、write_onlyフィールドを作成するなどの厄介なことをしてから、validateandto_representationメソッドをオーバーライドする必要があります。これは私のために働いたものです:

class FooSerializer(ModelSerializer):

    foo = CharField(write_only=True)

    class Meta:
        model = Foo
        fields = ["foo", ...]

    def validate(self, data):
        foo = data.pop("foo", None)
        # Do what you want with your value
        return super().validate(data)

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data["foo"] = whatever_you_want
        return data
于 2020-08-12T16:17:19.237 に答える