在反向关系上添加Serializer - Django Rest Framework

Mar*_*ind 13 django rest django-rest-framework

我有一个Cart模型和一个CartItem模型.该CartItem模型具有ForeignKeyCart模型.

使用Django Rest Framework我有一个API用户可以显示的视图Cart,显然我希望包含CartItem在respone中.

我像这样设置我的Serializer:

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', 
        )
Run Code Online (Sandbox Code Playgroud)

我的问题是第二行,cartitem_set = CartItemSerializer(read_only=True).

我得到了AttributeErrors说'RelatedManager' object has no attribute 'product'.('product'是CartItem模型中的一个字段.如果我从产品中排除产品,CartItemSerializer只会在下一个字段中获得一个新的AttributeError,等等.无论我是否只在Serializer中留下1个或所有字段,我都会收到错误.

我的猜测是,由于某种原因,Django REST Framework不支持添加Serializers来反转这样的关系.我错了吗?我该怎么做?

PS

我想使用它的原因CartItemSerializer()是因为我想控制响应中显示的内容.

Mar*_*ind 14

艾哈迈德·霍斯尼的回答是正确的.它要求将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', 
        )
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过执行以下操作来更改名称:items = CartItemSerializer(read_only = True,many = True,source ='cartitem_set') (3认同)
  • 您可以从related_name 更改cartitem_set 名称。在 CartItem 类中:cart = models.ForeignKey(Cart, related_name='items') ,然后在序列化程序中的“字段”中,您必须使用名称项 (3认同)
  • 我们可以将名称cartitem_set更改为items吗? (2认同)

djq*_*djq 6

在模型中定义相关名称并在序列化程序关系中使用该相关名称很重要:

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()
Run Code Online (Sandbox Code Playgroud)

然后在您的序列化器定义中使用这些确切的名称:

class CartSerializer(serializers.ModelSerializer):
    cart_items = CartItemSerializer(read_only=True)
    class Meta:
       model = Cart
       fields = ('name', 'cart_items',)
Run Code Online (Sandbox Code Playgroud)