私の個人的なジャンゴレストフレームワーク



今日の前に、私の手と私の手を読むことができる神だけでした、しかし、今日、それはそうすることができる神です.今日、私は私のDRFドラフトの1つを読んで立ち往生しましたserializers そして、私は私が私のノートを保存することができますブログを持っている必要があります-と私はすでにそれを忘れるブログを持っている必要があると考え始めると、その年のその時間だと決めたblog 私はなぜ🤔 ? ... 私のDRFシリアライザーのノートのデジタルコピーを作成してみましょう、誰かが役に立つでしょう.

save time creating django apis with this cool django package, and support the repository by dropping a star ⭐


将来参照のインデックスやテーブルを定義しましょう.

目次
1 - Fields
  --------------------------
  - Serializer Method Field
  - Read Only Field
  - Custom Field Validation
  - Using Multiple Serializers
  --------------------------
2 - Data
  --------------------------
  - Custom Data Validation
  - Custom Output with `to_representation`()
  - Custom Input with `to_internal_value`().
  - Pass additional data directly to `save()`
  --------------------------
3 - Keywords
  --------------------------
  - The `source` Keyword
  - The `context` Keyword

1 -フィールド

シリアライザーメソッドフィールド
これは読み取り専用フィールドです.それは、それが付けられるSerializerクラスのメソッドを呼ぶことによって、その値を得ます.これは、オブジェクトのシリアル化された表現にデータの任意の並べ替えを追加するために使用することができます.SerializerMethodField 呼び出してデータを取得するget_<field_name> .
例:
class UserSerializer(serializers.ModelSerializer):
    days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = '__all__'

    def get_days_since_joined(self, obj):
        return (now() - obj.date_joined).days

読み取り専用フィールド
読み込み専用フィールドはAPI出力に含まれていますが、CREATEまたはUPDATE操作中に入力に含まれてはなりません.任意read_only シリアライザー入力に正しく含まれないフィールドは無視されます.
例:
class AccountSerializer(serializers.Serializer):
    id = IntegerField(label='ID', read_only=True)

カスタムフィールド確認
Django REST Frameworkのシリアルライザーでのバリデーションは、DjangoのModelFormクラスで検証がどのように動作するかに少し異なります.
modelformで、妥当性は部分的にフォームで実行されます、そして、部分的にモデルのインスタンスで.RESTフレームワークを使用すると、検証は完全にシリアライザークラスで実行されます.
12歳から18歳までの学生を許可したい例を挙げましょう.
class StudentSerializer(serializers.ModelSerializer):
    ...
    def validate_age(self, age):
        if age > 18 or age < 12:
            raise serializers.ValidationError('Age has to be between 12 and 18.')
        return age

複数のシリアライザーの使用
あなたは、get_serializer_class() あなたのViewSet たとえば、次のように、次のように別のシリアライザーを使用して、CreateおよびUpdateアクションを使用します.
class MyViewSet(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()

    def get_serializer_class(self):
        if self.action in ["create", "update"]:
            return WriteSerializer
        return ReadSerializer

2 -データ

カスタムデータの検証
カスタムフィールドバリデーションのほかに、データを検証するために2つの追加の方法があります.たとえば、いくつかのフィールドを互いに比較する必要がある場合には、オブジェクトレベルでの最善の方法です.
例:
class OrderSerializer(serializers.ModelSerializer):
    ...
    def validate(self, data):
        if data['discount_amount'] > data['total_amount']:
            raise serializers.ValidationError('discount cannot be bigger than the total amount')
        return data
妥当性検査を行うもう一つの良い方法は、検証ロジックをいくつかのシリアル化装置で複数回繰り返すと、関数にそれを抽出することができます.
def is_valid_age(value):
    if age < 12:
        raise serializers.ValidationError('age cannot be lower than 12.')
    elif age > 18:
        raise serializers.ValidationError('age cannot be higher than 18')
その後、他のシリアルライタでこのように渡すことができます.
class AnotherSerializer(serializers.ModelSerializer):
    age = IntegerField(validators=[is_valid_age])

カスタム出力to_representation()使用する前に出力をカスタマイズしたい場合to_representation() , シリアル化が完了した後、次のような出力を持っていると想像してください.
{
  "id": 1,
  "username": "abdenasser",
  "bio": "Hey ... you already know!",
  "followed_by": [2, 3]
}
そして、あなたはそれに合計フォロワーカウントを追加します.簡単にできます.
class ResourceSerializer(serializers.ModelSerializer):
    ...
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        representation['followers'] = instance.followed_by.count()
        return representation
それから、あなたは得るでしょう:
{
  "id": 1,
  "username": "abdenasser",
  "bio": "Hey ... you already know!",
  "followed_by": [2, 3],
  "followers": 2
}

カスタム入力to_internal_value()あなたのAPIがサードパーティサービスからいくつかの入力を期待していて、あなたがその入力のチャンクに興味があるだけであると言いましょうto_internal_value() 次のようにします.
class SomeSerializer(serializers.ModelSerializer):
    ...
    def to_internal_value(self, data):
        useful_data = data['useful']
        return super().to_internal_value(useful_data)

SAVE ()に直接追加データを渡します.
呼び出し.save() シリアライザークラスをインスタンス化するときに既存のインスタンスが渡された場合によって、新しいインスタンスを作成するか、既存のインスタンスを更新します.
# .save() will create a new instance.
serializer = CommentSerializer(data=data)

# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)

3 -キーワード

ソースキーワード
本質的に、あなたはsource こんな分野で
field_name = serializers.SomeFieldType(source='prop')
どこprop いくつかの値を返す関数、あるいは関連するモデルに存在するプロパティの呼び出し...(source='author.bio') または、出力で名前を変更するシリアライザーフィールドでも.
また、オブジェクト全体を添付することができますsource='*' 必要ならば.

コンテキストキーワード
シリアライザーをインスタンス化するときにコンテキスト引数を渡すことで、任意の追加コンテキストを提供できます.例えば、
resource = Resource.objects.get(id=1)
serializer = ResourceSerializer(resource, context={'key': 'value'})
文脈辞書は、それから任意のSerializerフィールドロジック(例えばカスタム)の範囲内で使用されることができる.selfにアクセスすることで、メソッドを追加します.コンテキスト属性.
def to_representation(self, instance):
    representation = super().to_representation(instance)
    representation['key'] = self.context['key']

    return representation

最終語:
ジャンゴレストフレームワークは、非常に良いドキュメントを見つけることができますhere , それにいくつかの時間を費やすし、あなたのシリアルライザーで複雑になっていることを感じた任意の時点でフォールバックとして使用してください、また、あなたがシリアルライザーを使用している間、あなたがほとんどの時間を使用している間、ベースシリアライザ機能を使用して、オーバーライドしたり拡張したりするので、それをチェックして、それを見てくださいhere .