python - Django 休息框架。更新嵌套对象

标签 python django rest django-rest-framework

我在更新嵌套对象时遇到问题。

所以我有一个结构类似于这个的模型:

class Invoice(models.Model):
    nr = models.CharField(max_length=100)
    title = models.CharField(max_length=100)

class InvoiceItem(models.Model):
    name = models.CharField(max_length=100)
    price = models.FloatField()
    invoice = models.ForeignKey(Invoice, related_name='items')

我需要从父对象创建子对象,我的意思是在创建 Invoice 对象时直接创建 InvoiceItems。 为此,我编写了以下序列化程序:

class InvoiceItemSerializer(serializers.ModelSerializer):
    invoice = serializers.PrimaryKeyRelatedField(queryset=Invoice.objects.all(), required=False)
    class Meta:
        model = InvoiceItem


class InvoiceSerializer(serializers.ModelSerializer):
    items = InvoiceItemSerializer(many=True)

    class Meta:
        model = Invoice

    def create(self, validated_data):
        items = validated_data.pop('items', None)
        invoice = Invoice(**validated_data)
        invoice.save()
        for item in items:
            InvoiceItem.objects.create(invoice=invoice, **item)
        return invoice

到目前为止,create/read/delete 方法都可以正常工作,除了 update。 我认为下面的逻辑应该是正确的,但它遗漏了一些东西。

def update(self, instance, validated_data):
    instance.nr = validated_data.get('nr', instance.nr)
    instance.title = validated_data.get('title', instance.title)
    instance.save()

    # up till here everything is updating, however the problem appears here.
    # I don't know how to get the right InvoiceItem object, because in the validated
    # data I get the items queryset, but without an id.

    items = validated_data.get('items')
    for item in items:
        inv_item = InvoiceItem.objects.get(id=?????, invoice=instance)
        inv_item.name = item.get('name', inv_item.name)
        inv_item.price = item.get('price', inv_item.price)
        inv_item.save()

    return instance

任何帮助将不胜感激。

最佳答案

这就是我完成任务的方式:

我已将 id 字段添加到 InvoiceItemSerializer

class InvoiceItemSerializer(serializers.ModelSerializer):
    ...
    id = serializers.IntegerField(required=False)
    ...

以及InvoiceSerializer

的更新方法
def update(self, instance, validated_data):
    instance.nr = validated_data.get('nr', instance.nr)
    instance.title = validated_data.get('title', instance.title)
    instance.save()

    items = validated_data.get('items')

    for item in items:
        item_id = item.get('id', None)
        if item_id:
            inv_item = InvoiceItem.objects.get(id=item_id, invoice=instance)
            inv_item.name = item.get('name', inv_item.name)
            inv_item.price = item.get('price', inv_item.price)
            inv_item.save()
        else:
            InvoiceItem.objects.create(account=instance, **item)

    return instance

同样在 create 方法中,如果通过了 id,我将弹出它。

关于python - Django 休息框架。更新嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37240621/

相关文章:

python - 按 ID 和周数计算单列中的滚动变化

python - 如何更新数组值并对新值执行相同的操作

python - 如何通过添加<span>来修改Django的某部分内容,同时保持段落文本的原始格式?

python - 修复应用级别允许的并发 session 数的方法。 Django

java - 从 rest 模板获取打开的输入流以进行大文件处理

java - Rest Template - 如何在发送之前检索原始 POST 请求字符串

python - 从普通函数调用生成器函数

python - 基于 python 的 webapp 中的并发处理

Django 管理员 : Making mandatory fields non-mandatory dynamically

java - Spring - 是否可以在请求映射中为两种不同的 post 方法提供相同的 url(路径)?