代码之家  ›  专栏  ›  技术社区  ›  Marcus Lind

在反向关系上添加序列化程序-Django Rest框架

  •  26
  • Marcus Lind  · 技术社区  · 10 年前

    我有一个 Cart 模型和a CartItem 模型这个 购物车项目 模型具有 ForeignKey 运货马车 模型

    使用Django Rest Framework,我有一个API用户可以显示 运货马车 ,显然,然后我想包括 购物车项目 在回应中。

    我这样设置序列化程序:

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

    我得到AttributeErrors说 'RelatedManager' object has no attribute 'product' .(“产品”是 购物车项目 模型如果我从 CartItemSerializer 我只是得到一个新的AttributeError和下一个字段,以此类推。无论我在Serializer中只留下1个或所有字段,我都会得到一个错误。

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

    附言

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

    3 回复  |  直到 10 年前
        1
  •  32
  •   Marcus Lind    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', 
            )
    
        2
  •  12
  •   djq    10 年前

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

    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',)
    
        3
  •  0
  •   ChampR    8 年前

    最好共享整个代码,即模型和序列化程序类。然而,这可能有助于调试错误,

    我的序列化程序类

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