【问题标题】:Django: Object attribute not saving/updatingDjango:对象属性不保存/更新
【发布时间】:2026-01-15 17:10:02
【问题描述】:

我有以下型号:

class Device(models.Model):
    #more_code
    supplier = models.ForeignKey(
        Supplier, on_delete=SET_NULL, blank=True, null=True, related_name="devices"
    )

我需要一个 Patch 端点来从设备更改供应商。视图中的所有内容看起来都可以正常工作,只有 device.save() 不会更新对象的状态

这是我的看法:

def patch(self, request, site_pk):
    """
    PATCH the device's supplier info of the site.
    """
    all_device_token = False
    if request.data.get("device") == "ALL":
        all_device_token = True
        arguments = {}
    else:
        device_pk = request.data.get("device")
        arguments = {"id": device_pk}

    devices = Device.objects.filter(site_id=site_pk, **arguments).all()
    if not devices.exists():
        raise PermissionDenied("The device does not belong to the site.")

    if all_device_token:
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(
            devices, many=True, data=request.data, partial=True,
        )
        serializer.is_valid(raise_exception=True)
        new_supplier = get_object_or_404(Supplier, pk=request.data.get("supplier"))
        for device in devices:
            device.supplier.id = new_supplier.pk
            device.supplier.name = new_supplier.name
            device.save()
    else:
        device = devices.first()

        serializer_class = self.get_serializer_class()
        serializer = serializer_class(device, data=request.data, partial=True,)
        serializer.is_valid(raise_exception=True)

        if "supplier" in self.request.data:
            new_supplier = serializer.validated_data["supplier"]
            device.supplier.id = new_supplier.pk
            device.supplier.name = new_supplier.name
            device.save()

        # serializer.save()
    return Response(serializer.data, status=status.HTTP_200_OK)

我的序列化程序正在返回正确的信息。 我看到头顶上有什么东西吗?

【问题讨论】:

  • 你不应该device.save(),而是device.supplier.save(),因为那是你正在更新的对象。话虽如此,您应该更改主键。只需创建一个新的Supplier(包含新内容),然后让您的devices 引用那个。

标签: python django crud


【解决方案1】:

您在这里使用新的主键和新的name 更新supplier 对象:

new_supplier = get_object_or_404(Supplier, pk=request.data.get('supplier'))
for device in devices:
    device.supplier.id = new_supplier.pk
    device.supplier.name = new_supplier.name
    device.save()

但我强烈建议不要更改旧供应商的主键(也不要重复数据)。如果你这样做了,你应该保存device.supplier.save(),因为你更新了那个对象。

但这样做不是一个好习惯,因为从那时起您更改了 Supplier object 而您不想更改旧供应商的名称,您想链接 @ 987654326@ 到新的Supplier。您可以通过设置supplier_id 外键来做到这一点,并保存设备:

supplier_id = request.data.get('supplier')
for device in devices:
    device.supplier_id = supplier_id
    device.save()

【讨论】:

    最近更新 更多