Django Rest Framework PUT请求对唯一模型字段

标签 django django-models django-rest-framework django-serializer

我有以下型号

class Owner(models.Model):
    user    = models.OneToOneField(User, default=1, editable=True)
    phone   = models.CharField(max_length=40, null=True, blank=True)
    address = models.CharField(max_length=255, null=True, blank=True)
    city    = models.CharField(max_length=255, null=True, blank=True)
    state   = USStateField(null=True, blank=True)
    zip     = models.CharField(max_length=20, null=True, blank=True)

    def __str__(self):
        return "%s %s" % (self.user.first_name, self.user.last_name)


class Device(CreationModificationMixin):

    _STATUSES = (
        ('A', 'Active'),
        ('I', 'Inactive'),
        ('F', 'Failure'),
    )

    _TYPES = (
        ('S', 'Spa'),
        ('P', 'Pool'),
    )

    udid    = models.CharField(max_length=255, verbose_name="Unique ID / MAC Address", null=False, blank=False, unique=True)
    type    = models.CharField(max_length=1, choices=_TYPES, null=False, blank=False)
    title   = models.CharField(max_length=255, null=False, blank=False)
    status  = models.CharField(max_length=1, default='A', choices=_STATUSES)
    pinged  = models.DateTimeField(null=True)
    owner   = models.ForeignKey(Owner, verbose_name="Owner", null=True, blank=True)

    def __str__(self):
        return self.udid

我有以下序列化程序
class DeviceSerializer(serializers.ModelSerializer):

    class Meta:
        model = Device
        fields = ('id', 'udid', 'title', 'type', 'status', 'pinged', 'created')

我定义了以下 API View :
class DeviceAPIView(APIView):
    permission_classes = (IsAuthenticated,) # explicit
    code_404 = "Device doesn't exists"

    def get(self, request, device_id):

        try:
            d = Device.objects.get(id=device_id, owner=request.user.owner)
        except Device.DoesNotExist:
            return Response({'error': self.code_404}, 404)

        serializer = DeviceSerializer(d)
        return Response(serializer.data)

    def put(self, request, device_id):

        serializer = DeviceSerializer(data=request.DATA)

        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        else:
            data = serializer.data
            data['id'] = id
            d = Device(**data).save()
            serializer = DeviceSerializer(d)
            return Response(serializer.data, status=status.HTTP_200_OK)

现有设备上的 PUT 请求
{
    "udid": "38-2C-4A-47-C2-ED",
    "title": "Backyard pool",
    "type": "S"
} 

还给我
{
    "udid": ["This field must be unique."]
}

但是,我正在更新记录并传递与它相同的 UDID。所以我没有在 DB 中得到重复,但 DRF 认为另一种方式。

我需要实现的是
  • 如果同一记录的 UDID 未更改 - 则不应引发错误
  • 如果记录的 UDID 更改,现在它与某些记录的 UDID 相同,则应返回错误。
  • 最佳答案

    根据实现 put 的评论方法更接近于 the docs 中的引用实现应该解决这个问题。

    def put(self, request, pk, format=None):
        device = self.get_object(pk)
        serializer = DeviceSerializer(device, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    

    Saving instances有更多关于使用 serializer 创建、更新和保存实例的信息。类方法。

    关于Django Rest Framework PUT请求对唯一模型字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30677764/

    相关文章:

    python - 如何更改 url 路由器 DRF 中的参数名称?

    python - 在 Django REST 框架中,如何在使用 ModeViewSet 时允许部分更新?

    python - 如何在 Netbeans 8.0.2 中创建 Django 项目

    python - Django - 在 'INSTALLED APPS' 中添加应用程序名称时出现值错误

    python - django 信号是否也包含在 transaction.atomic 装饰器中?

    django - 调用 News.objects.all()[ :x] to fetch fixed number of records 是否正确

    django - 如何将 Django 信号与抽象模型一起使用?

    rest - 是不是rest API路由按权限分开比较好?

    iOS Swift 3 发布问题

    python - Django:在 models.py 中出错并迁移,尝试修复错误,但 django 在 models.py 中没有看到任何更改