【问题标题】:DRF: creating new object in a model with 'ManyToMany' field and 'through' tableDRF:在具有“ManyToMany”字段和“through”表的模型中创建新对象
【发布时间】:2018-08-01 09:07:10
【问题描述】:

我有以下 Django 模型:

class Product(models.Model):
    name = models.CharField(max_length=250, unique=True)
    quantity = models.IntegerField(default=0)

class Order(models.Model):
    products = models.ManyToManyField(
        Product,
        through='PositionInOrder'
    )
    discount = models.CharField(max_length=50, blank=True)
    total_sum = models.DecimalField(max_digits=11, decimal_places=2, default=0)

class PositionInOrder(models.Model):
    sale = models.ForeignKey(Order)
    product = models.ForeignKey(Product)
    quantity = models.PositiveIntegerField()
    price = models.PositiveIntegerField()

以及以下序列化程序:

class ProductSerializer(serializers.ModelSerializer):

    class Meta:
        model = Product
        fields = '__all__'

class PositionInOrderSerializer(serializers.HyperlinkedModelSerializer):
    sale = serializers.ReadOnlyField()
    product = serializers.ReadOnlyField()

    class Meta:
        model = PositionInOrder
        fields = "__all__"

class OrderSerializer(serializers.ModelSerializer):
    products = PositionInOrderSerializer(many=True)

    def create(self, validated_data):
        products = validated_data.pop('products')
        order = Order.objects.create(**validated_data)
        return order

    class Meta:
        model = Order
        fields = '__all__'

我想创建新订单。发送包含此 json 的 post 查询:

{
    "products": [{"id": 2606, "name": "Some name", "quantity": 140, "price": 250}],
    "discount": "15",
    "total_sum": 500
}

在 OrderSerialization 类的 create() 方法中,我得到 products=: [OrderedDict([('quantity', 140), ('price', 250)])] 并且没有关于 product_id 和产品名称。我怎样才能得到它们?

【问题讨论】:

  • 为什么在OrderSerializer 中使用PositionInOrderSerializer 而不是ProductSerializer
  • 我的代码基于这个答案:stackoverflow.com/a/17263583/4786619 我使用带有直通表的模型,因此我必须使用 PositionInOrderSerializer。

标签: django django-models django-rest-framework many-to-many django-orm


【解决方案1】:

尝试在PositionInOrderSerializer 中显式定义idname 字段:

class PositionInOrderSerializer(serializers.HyperlinkedModelSerializer):
    sale = serializers.ReadOnlyField()
    id = serializers.IntegerField(source='product.id')
    name = serializers.IntegerField(source='product.name')

    class Meta:
        model = PositionInOrder
        fields = "__all__"

【讨论】:

  • 是的,现在可以了!谢谢!稍微改正一下,应该是:name = serializers.CharField(source='product.name')
猜你喜欢
  • 2020-02-09
  • 2012-02-27
  • 2014-02-04
  • 1970-01-01
  • 2015-04-04
  • 2021-09-26
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多