web-dev-qa-db-ja.com

逆の関係にシリアライザを追加-Django Rest Framework

CartモデルとCartItemモデルがあります。 CartItemモデルには、ForeignKeyモデルに対するCartがあります。

Django Rest Frameworkを使用しています。APIユーザーがCartを表示できるビューがあります。そして、当然、CartItemを応答に含めたいと思います。

私はシリアライザを次のように設定しました:

_class CartSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)
    cartitem_set = CartItemSerializer(read_only=True)
    class Meta:
        model = Cart
        depth = 1
        fields = (
            'id', 
            'user', 
            'date_created', 
            'voucher', 
            'carrier', 
            'currency', 
            'cartitem_set', 
        )
_

私の問題は2行目のcartitem_set = CartItemSerializer(read_only=True)です。

AttributeErrorsに_'RelatedManager' object has no attribute 'product'_と表示されます。 ( 'product'はCartItemモデルのフィールドです。CartItemSerializerからproductを除外すると、次のフィールドなどで新しいAttributeErrorが発生するだけです。1のままにしてもかまいません。またはシリアライザのすべてのフィールドでエラーが発生します。

私の推測では、何らかの理由でDjango REST Frameworkは、このような関係を逆にするシリアライザの追加をサポートしていません。間違っているのでしょうか?どうすればよいですか?

PS

CartItemSerializer()を使用する理由は、応答に表示される内容を制御したいためです。

15
Marcus Lind

アーメド・ホスニーの答えは正しかった。機能するには、manyパラメータをTrueに設定する必要がありました。

したがって、CartSerializerの最終バージョンは次のようになります。

class CartSerializer(serializers.ModelSerializer):
    cartitem_set = CartItemSerializer(read_only=True, many=True) # many=True is required
    class Meta:
        model = Cart
        depth = 1
        fields = (
            'id', 
            'date_created', 
            'voucher', 
            'carrier', 
            'currency', 
            'cartitem_set', 
        )
16
Marcus Lind

モデルに関連名を定義し、その関連名をシリアライザー関係で使用することが重要です。

class Cart(models.Model):
   name = models.CharField(max_length=500)

class CartItem(models.Model):
   cart = models.ForeignKey(Cart, related_name='cart_items')
   items = models.IntegerField()

次に、シリアライザーの定義で、これらの正確な名前を使用します。

class CartSerializer(serializers.ModelSerializer):
    cart_items = CartItemSerializer(read_only=True)
    class Meta:
       model = Cart
       fields = ('name', 'cart_items',)
2
djq

モデル全体とシリアライザクラスであるコード全体を共有することをお勧めします。ただし、おそらくこれはエラーのデバッグに役立ちます。

私のシリアライザクラス

class CartItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = CartItem
        fields = ('id')

class CartSerializer(serializers.ModelSerializer):

    #take note of the spelling of the defined var
    _cartItems = CartItemSerializer()
    class Meta:
        model = Cart
        fields = ('id','_cartItems')

今モデルのために

class CartItem(models.Model):
    _cartItems = models.ForeignKey(Subject, on_delete=models.PROTECT)
    #Protect Forbids the deletion of the referenced object. To delete it you will have to delete all objects that reference it manually. SQL equivalent: RESTRICT.
class Meta:
    ordering = ('id',)

class Cart(models.Model):
    class Meta:
    ordering = ('id',)

Django-rest-frameworkの関係の詳細な概要については、公式の ドキュメント を参照してください

0
Reuben Mugambi