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

时间:2016-02-09 06:45:24

标签: django rest django-rest-framework

我有Cart模型和CartItem模型。 CartItem模型对ForeignKey模型有Cart

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

我设置了这样的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', 
        )

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

我得到属性错误'RelatedManager' object has no attribute 'product'。 ('产品'是CartItem模型中的字段。如果我从CartItemSerializer中排除产品,我只会在下一个字段中获得新的AttributeError,依此类推。无论我是否只留下Serializer中的1个或所有字段,我会收到错误。

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

PS

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

3 个答案:

答案 0 :(得分:10)

艾哈迈德·霍斯尼的回答是正确的。它需要将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', 
        )

答案 1 :(得分:1)

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

<ul class="appul">
  <li>08:00</li>
  <li>08:15</li>
  <li>08:30</li>
  <li>08:45</li>
  <li>09:00</li>
  <li>09:15</li>
  <li>09:30</li>
  <li>09:45</li>
  <li>10:00</li>
  <li>10:15</li>
  <li>10:30</li>
  <li>10:45</li>
  <li>10:30</li>
  <li>10:45</li>

</ul>

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

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()

答案 2 :(得分:0)

共享整个代码(即模型和序列化器类)是明智的。但是,也许这可以帮助您调试错误,

  

我的序列化程序类

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中关系的详细概述,请参阅其官方documentation