2016-07-19 10 views
7

私はそれに多くのリンクを持つモデルを持っています。これらのモデルのネストしたシリアルツィアからモデルを作成せずにシリアライザを使用してモデルインスタンスを作成するにはどうすればよいですか?

class Travel(BaseAbstractModel): 

    tags = models.ManyToManyField(
     Tag, 
     related_name='travels', 
     ) 
    owner = models.ForeignKey(
     'users.TravelUser', 
     related_name='travel_owner' 
     ) 
    payment = models.ForeignKey(
     Payment, 
     related_name='travels', 
     ) 
    country = models.ForeignKey(
     Country, 
     related_name='travels, 
     ) 
    ........ 

多くは、固有の名前とイメージを持つ2つのフィールドのみを持っています。 私はこれらのモデルのそれぞれのシリアライザを作成し、ドキュメントに基づいて、私はcreate()updateを上書きTravelSerializer

class TravelBaseSerializer(DynamicFieldsModelSerializer): 

    owner = UserSerializer(required=False) 
    tags = TagSerializer(many=True) 
    payment = PaymentSerializer() 
    country = CountrySerializer() 

に入れ。
問題は、JSONデータを送信したときに、Djangoがネストされたシリアライザから各モデルを作成することです。しかし、作成するのはTravelインスタンスだけです。また、私は受信し、pkフィールドだけでなく、シリアル化されたオブジェクトに応答します。

更新
私はこの問題を解決し、答えにコードを入れました。これで、オブジェクトを作成せずにシリアライザのデータを受信して​​応答できます。 しかし私はDRFがよりエレガントなアプローチを提供していると思います。 DRFを使った私の最初のプロジェクトです。多分私は何かを見逃してしまい、もっと簡単な解決策があります。

class NestedRelatedSerializer(serializers.ModelSerializer): 

    def to_internal_value(self, data): 
     try: 
      pk = data['pk'] 
     except (TypeError, KeyError): 
     # parse pk from request JSON 
      raise serializers.ValidationError({'_error': 'object must provide pk!'}) 
     return pk 

はそれからすべてのpkを取得し、createupdated方法で保存します:私は「

def update(self, instance, validated_data): 
     # If don't get instance from db, m2m field won't update immediately 
     # I don't understand why 
     instance = Travel.objects.get(pk=instance.pk) 
     instance.payment_id = validated_data.get('payment', instance.payment_id) 
     instance.country_id = validated_data.get('country', instance.country_id) 
     # update m2m links 
     instance.tags.clear() 
     instance.tags.add(*validated_data.get('tags')) 
     instance.save() 
     return instance 

答えて

2

私はオーバーライドto_internal_value()は、カスタムserailizerに入れて、そこからすべてのネストされたシリアライザを継承決めますあなたが何をしたいのか分かりませんが、read_only_fieldsMetaクラスです。

class TravelBaseSerializer(DynamicFieldsModelSerializer): 

    owner = UserSerializer(required=False) 
    tags = TagSerializer(many=True) 
    payment = PaymentSerializer() 
    country = CountrySerializer() 

    class Meta: 
     read_only_fields = ('tags',) 

ドキュメントのthis sectionを参照してください。

1

+0

ありがとうございますが、最初に試しました。 'read_only_fields'の問題です。これらのフィールドは' validated_data'に渡されません。 –

+0

OKこれはあなたの望むものです。あなたのシリアライザを使って子犬を読んで、関連するすべてのフィールドをシリアライズします。 puprosesは、関連するフィールドを検証しますが、保存しません。私が間違っているなら、私を修正してください。 – AntoineWDG

+0

はい、 'validated_data'にこのデータが必要です。作成された' Travel'モデルですべてのリンクフィールドを埋める必要があるからです。あなたが私の答えで見ることができるように、私はそれを解決する。しかし、私はこのような目的のためにいくつかのベストプラクティスを見つけたいので、この恩恵を始めます。今では、DRFはそのような目的でネストされたシリアライザをデフォルトで使用することを許可していません。 –

関連する問題