2017-05-09 6 views
1

DjangoとDRFの最新バージョンを使用しています。Django Restフレームワーク、ModelSerializersおよびカスタムフィールドの検証

私は解決策を見つけることができないかなり複雑な要件があります。私はそれを単純化しようとします。

私は2つのフィールドを持つモデルを持っているとしましょう。 field_aおよびfield_b

私はModelSerializerを持っています。私はPOSTのフィールドでリクエストします。フィールドはモデルで検証され、次に2つのシリアライザ関数validate_field_avalidate_field_bに対して検証されます。すべては順調です。

今、私はそのモデルのメンバーではない3番目のフィールドを含むように私のPOST要求をしたいと思います。 field_cとしましょう。私はデータベースにすべてを保存するシリアライザにカスタムdef create(self, validated_data):を持っています。 field_cへに関して

私はしたいと思います:

  1. カスタム、それを検証します。他の2つのフィールドと同じように。
  2. 全体の要求が成功するために必須であり、そうでない場合、私は必要なモデルのフィールドのいずれかをPOSTするのを忘れているかのように「フィールドが必要です」というエラーを発行する必要があります。
  3. field_cをとり、db内の全く異なるモデルの行に保存してください。

私はそれを回避するように見えることはできません。 field_cfieldsメタに追加すると、field_cが私のモデルに存在しないという例外がスローされます。私がフィールドにそれを含めなければ、私が実際にそこに入れたいと思っているvalidate_field_cは呼ばえされません。

どうすればよいですか?

答えて

3

カスタムフィールドの値を扱うことができるようにあなたはwrite_onlyフィールドとして、あなたのシリアライザにカスタムフィールドを追加し、作成メソッドをオーバーライドすることができます。このような

何か:

class MySerializer(serializers.ModelSerializer): 
    field_c = serializers.CharField(write_only=True) 

    class Meta: 
     model = MyModel 
     fields = ('field_a', 'field_b', 'field_c') 

    def validate_field_c(self, value): 
     if value is 'test': 
      raise ValidationError('Invalid') 
     return value 

    def create(self, validated_data, **kwargs): 
     field_c = validated_data.pop('field_c') 

     return MyModel.objects.create(**validated_data) 
+0

素晴らしいです。そのトリックをした。ありがとう。 – JasonGenX

+0

うれしかった! –

0

ModelSerializerを使用しないでください。モデルと同じフィールドを再作成するシリアライザを使用してください。field_cがあります。

私はあなたのモデルが検証プロセスにおける作業のいくつかをしたいが、DRFのデザインは、それがこれらの責任を分離するようなものであることを理解しています。あなたはそれについての詳細を読むことができますhere。基本的には、シリアライザはすべての検証を重い持ち上げるものでなければなりません。

もちろん、シリアライザで検証メソッドを明示的に定義する必要があります。カスタムcreate()方法で

あなたはモデルのインスタンスを作成したり、必要に応じて、あなたがそれでやりたいことができます。

関連する問題