【问题标题】:Django DRF - Updating many-to-one model in serializerDjango DRF - 在序列化程序中更新多对一模型
【发布时间】:2022-06-25 20:08:39
【问题描述】:

我的模型结构非常简单:一组条件通过外键引用一个Item的多对一关系。

这里我们有对应的serializers.py:

class ConditionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Condition
        fields = ('condition_id','name', 'left', 'operator', 'right')

 class ItemSerializer(serializers.ModelSerializer):
    conditions = ConditionSerializer(many=True, read_only=True)

    def create(self, validated_data):
        conditions_data = validated_data.pop("conditions")
        item = Item.objects.create(**validated_data)
        for condition_data in conditions_data:
            Condition.objects.create(item=item, **condition_data)
        return item

    def update(self, instance, validated_data):
        instance.name = validated_data.get('name', instance.name)
        conditions_data = validated_data.get('conditions', instance.conditions)
        for c in conditions_data.all():
            print(c.name)   # it correctly prints out the value
        instance.conditions.set(conditions_data.all())   # Doesn't update the instance
        instance.save()
        return instance

    class Meta:
        model = Item
        fields = ('item_id', 'name', 'conditions')

问题出在 update 函数中: instance.name 已正确更新; instance.conditions.set(conditions_data.all()) 不是

没有错误显示,因为响应是 200OK。

我还把Condition对象(name)的field的for循环打印,显示成功,说明数据读取正确。

我试图解决从 ConditionSerializer 中删除 read_only=True 的问题,但由于收到错误,情况变得更糟:

AttributeError: 'list' 对象没有属性 'all'

可能问题与外键管理有关。

有没有办法解决这个问题?

更新:这里是模型

class Item(models.Model):
    item_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
    created_on = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)
    name = models.CharField(max_length=64)
      
    readonly_fields=['item_id','created_on','last_updated']
     
class Condition(models.Model):
    condition_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
    name = models.CharField(max_length=128)
    left = models.JSONField()
    operator = models.CharField(max_length=2)
    right = models.JSONField()
    item = models.ForeignKey(Item, related_name="conditions", on_delete=models.CASCADE, null=True)

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    我认为你需要设置他们的 ID。

    class ItemSerializer(serializers.ModelSerializer):
        conditions = ConditionSerializer(many=True, read_only=True)
        ...
    
        def update(self, instance, validated_data):
            instance.name = validated_data.get('name', instance.name)
            conditions_data = validated_data.get('conditions', instance.conditions)
            condition_ids = []
            for c in conditions_data.all():
                condition_ids.append(c.id)
            instance.conditions.set(condition_ids)
            instance.save()
            return instance
    

    【讨论】:

    • 感谢您的帮助,但它不起作用,因为 instance.conditions.set() 的参数需要一个 Condition 实例,而不是 id。我收到以下错误:“TypeError: 'Condition' instance expected, got UUID('1e9b73e8-7ffc-43f4-93b4-01f2c5467ac8')”
    • 什么是主键字段?他们是如何联系的?
    • 我用模型更新了问题。主键是condition_id(我用这个来测试你的代码)。
    • 那么不是c.id应该改成c.condition_id
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-22
    • 2017-03-22
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多