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()
を使用する理由は、応答に表示される内容を制御したいためです。
アーメド・ホスニーの答えは正しかった。機能するには、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',
)
モデルに関連名を定義し、その関連名をシリアライザー関係で使用することが重要です。
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',)
モデル全体とシリアライザクラスであるコード全体を共有することをお勧めします。ただし、おそらくこれはエラーのデバッグに役立ちます。
私のシリアライザクラス
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の関係の詳細な概要については、公式の ドキュメント を参照してください