1

私は次のモデルがあります:シリアル化ジェネリック関係、

class TaggedItem(models.Model): 
    tag = models.SlugField() 
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

私はAPIエンドポイントを経由してコンテンツオブジェクトを割り当てることができる方法で、このモデルをシリアル化しようとしていますが

は、これまでのところ、私はこれを行っている:

class TaggedItemSerializer(serializers.ModelSerializer): 
    content_object = serializers.RelatedField(read_only=True) 

    class Meta: 
     model = TaggedItem 

しかし、これは読み取り専用です。 read_onlyパラメータを削除した場合は、フィールドのクエリセットを指定する必要があります。しかし、私はこの一般的な関係のために多くの異なるモデルタイプを持っています。シリアライザ内とモデルの他の場所の両方ですべての可能なモデルタイプを指定すると、コードを複製しているようです。

object_idフィールドとcontent_typeフィールドでコンテンツオブジェクトを設定することもできますが、これを行うとエラーが発生します。例えば

{ 
    ... 
    object_id: 1, 
    content_type: 'auth.User' 
} 

は、私はDRF APIを介してこのcontent_object書き込み可能にするにはどうすればよい"detail": "JSON parse error - Expected object or value"

で400応答を返しますか?

答えて

3

このような.to_internal_value.validate.createメソッドオーバーライド:

from django.apps import apps 

class TaggedItemSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = TaggedItem 
     read_only_fields = ('content_type', 'object_id', 'content_object') 

    def to_internal_value(self, data): 
     object_id = data.pop('object_id') 
     content_type = data.pop('content_type') 

     ret = super(ConfigCalcSerializer, self).to_internal_value(data) 

     ret['object_id'] = object_id 
     ret['content_type'] = content_type 

     return ret 

    def validate(self, data): 
     object_id = data.pop('object_id') 
     content_type = data.pop('content_type') 

     Model = apps.get_model(content_type) 

     try: 
      content_object = Model.objects.get(id=object_id) 
     except Model.DoesNotExist: 
      raise serializers.ValidationError('Not found') 
     else: 
      data['content_object'] = content_object 

     return data 

    def create(self, validate_data): 
     return TaggedItem.objects.create(**validate_data) 
関連する問題