我有一个API端点,用于设备执行签入。
未知设备时:
CustomerDevice
实例DeviceStatus
相关的新CustomerDevice
实例API响应:
{
"customer_device_uuid": "646aaff6-debf-4281-bd7f-064dd6dc8ab8",
"device_group": {
"group_uuid": "ebd0990b-aeb5-46a4-9fad-82237a5a5118",
"device_group_name": "Default",
"color": "4286f4",
"is_default": true
}
}
已知设备时
DeviceStatus
实例,该实例与发出请求的设备有关。API响应:
{
"customer_device_uuid": "fbbdf1d1-766d-40a9-961f-2c5a5cb3db6e"
}
问题是已知设备执行签入时的API响应。返回的customer_device_uuid
在数据库中不存在,看起来像是随机生成的uuid
。
我希望已知设备的API响应与未知设备的API响应相同。
serializer.data
包含随机uuid,直到else
语句为止。 serializer.data
从那里包含我在响应中所需的数据。
我试图在self.perform_create
块中调用if
。这导致serializer.data
具有正确的响应数据。但是,无论设备是已知设备还是未知设备,这都会为每次签入创建一个新的CustomerDevice
和相关的DeviceStatus
。
我的views.py
:
class DeviceCheckinViewSet(viewsets.ModelViewSet):
serializer_class = CheckinSerializer
queryset = CustomerDevice.objects.all()
http_method_names = 'post'
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
# if the device is known -> just log the data
if CustomerDevice.objects.filter(device_id_android=serializer.validated_data['device_id_android']).exists():
self.log_device_status(request)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
# if device is not known -> link it to the customer and log the device data
else:
self.perform_create(serializer)
customer_device = CustomerDevice.objects.get(device_id_android=request.data['device_id_android'])
DeviceStatus.objects.create(
customer_device_id=customer_device.customer_device_uuid,
disk_space=request.data['disk_space'],
battery_level=request.data['battery_level'],
battery_cycles=request.data['battery_cycles'],
battery_health=request.data['battery_health']
)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
# creates new instance with default group
def perform_create(self, serializer):
serializer.save(group_uuid=get_default_group())
def log_device_status(request):
DeviceStatus.objects.create(
customer_device_id=request.data['customer_device_uuid'],
disk_space=request.data['disk_space'],
battery_level=request.data['battery_level'],
battery_cycles=request.data['battery_cycles'],
battery_health=request.data['battery_health']
)
我的serializers.py
class DeviceGroupSerializer(serializers.ModelSerializer):
class Meta:
model = DeviceGroup
fields = ('group_uuid', 'device_group_name', 'color', 'is_default')
class CheckinSerializer(serializers.ModelSerializer):
device_group = DeviceGroupSerializer(many=False, read_only=True, source='group_uuid')
class Meta:
model = CustomerDevice
fields = ('customer_device_uuid', 'customer_uuid', 'device_id_android', 'device_group')
extra_kwargs = {
'customer_uuid': {'write_only': True},
'device_id_android': {'write_only': True}
}
已知或未知设备时,以下API响应。
{
"customer_device_uuid": "646aaff6-debf-4281-bd7f-064dd6dc8ab8",
"device_group": {
"group_uuid": "ebd0990b-aeb5-46a4-9fad-82237a5a5118",
"device_group_name": "Default",
"color": "4286f4",
"is_default": true
}
}
将DeviceGroupSerializer()
添加到了serializers.py
相关models.py
:
# Customer table
class Customer(models.Model):
customer_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
customer_name = models.CharField(max_length=128, unique=True)
users = models.ManyToManyField('auth.User', related_name='customers')
def __str__(self):
return self.customer_name
class Meta:
db_table = 'customer'
# Device group table
class DeviceGroup(models.Model):
group_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
customer_uuid = models.ForeignKey(Customer, on_delete=models.DO_NOTHING)
device_group_name = models.CharField(max_length=20)
color = models.CharField(max_length=8)
is_default = models.BooleanField(default=False)
def __str__(self):
return self.device_group_name
class Meta:
db_table = 'device_group'
# Customer_device table
class CustomerDevice(models.Model):
customer_uuid = models.ForeignKey(Customer, on_delete=models.CASCADE)
customer_device_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
group_uuid = models.ForeignKey(DeviceGroup, null=True, blank=True, on_delete=models.SET(get_default_group))
device_id_android = models.CharField(max_length=100, blank=True, null=True) # generated by client
def __repr__(self):
return '%r' % self.customer_device_uuid
class Meta:
db_table = 'customer_device'
unique_together = (('customer_uuid', 'customer_device_uuid'),) # composite key
# Device status table
class DeviceStatus(models.Model):
device_status_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
disk_space = models.PositiveIntegerField(blank=True, null=True)
battery_level = models.PositiveIntegerField(blank=True, null=True)
battery_health = models.CharField(max_length=30)
battery_cycles = models.PositiveIntegerField(blank=True, null=True)
customer_device = models.ForeignKey(CustomerDevice, on_delete=models.CASCADE, related_name="customer_device")
def __repr__(self):
return '%r' % self.device_status_uuid
class Meta:
db_table = 'device_status'
答案 0 :(得分:1)
我已实例化了一个uuid为Customer
的{{1}}和一个e73141ab-883c-44bc-8ce2-21b492cab03e
设置为DeviceGroup
的{{1}},以便is_default
可以对其进行分配。
现在发生的是,当我使用以下命令调用端点时:
True
产生的响应是:
get_default_group
这正是您所需要的。我的假设是您的{
"customer_uuid": "e73141ab-883c-44bc-8ce2-21b492cab03e",
"customer_device_uuid": "444b944a-4bcf-4ea2-8860-1d3ca82fd1d3",
"device_id_android": "111",
"disk_space": 10,
"battery_level": 10,
"battery_health": "good",
"battery_cycles": 10
}
没有返回默认组。
第二次您的序列化程序没有产生您想要的输出的原因是因为您正在序列化请求数据而不是实例,并且在请求数据中没有{
"customer_device_uuid": "0d53c7d4-ce34-42ce-9dd8-5e7ea07c4438",
"device_group": {
"group_uuid": "5ee2f30e-bfd1-4f31-83ad-753d1d7220ad",
"device_group_name": "",
"color": "",
"is_default": true
}
}
,因此您需要请执行以下操作:
get_default_group