I have the following model
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
I have the following serializer
class DeviceSerializer(serializers.ModelSerializer):
class Meta:
model = Device
fields = ('id', 'udid', 'title', 'type', 'status', 'pinged', 'created')
I have the following API View defined:
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 request on existing device
{
"udid": "38-2C-4A-47-C2-ED",
"title": "Backyard pool",
"type": "S"
}
gives me back
{
"udid": ["This field must be unique."]
}
However I'm updating the record and passing the same UDID it has. So I'm not getting a duplicate in DB but DRF thinks the other way.
What I need to achieve is
As per the comments implementing the put
method closer to the reference implementation in the docs should fix the issue.
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 has a bit more information on creating, updating and saving instances by using the serializer
class methods.