我正在尝试为设备组和设备创建api。设备组可以有多个设备,我希望设备组具有多个设备的后api,因为只有在选择了设备且用户可能选择多个设备然后创建新组时才会显示组创建。这样,在创建组时,这些选定的设备也应显示为device_list
这是我的代码,我不确定如何发布请求
class BaseDevice(PolymorphicModel):
name = models.CharField(max_length=250, blank=False, null=False)
group = models.ForeignKey('DeviceGroup', related_name="groups", null=True, blank=True)
class Device(BaseDevice):
description = models.TextField(blank=True, null=True)
class DeviceGroup(models.Model):
name = models.CharField(max_length=250, blank=False, null=False)
class DeviceIdSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source='token', format='hex', read_only=True)
class Meta:
model = Device
# id is the token of the device and name is the name of the device
fields = ('id', 'name')
class DeviceGroupSerializer(serializers.ModelSerializer):
name = serializers.StringRelatedField()
device_list = DeviceIdSerializer(read_only=False, many=True, required=False, source="groups")
class Meta:
model = DeviceGroup
# name is the name of group created and device_list is the list of devices with id(token) and device name
fields = ('id', 'name', 'device_list')
def create(self, validated_data):
print ('validated_data', validated_data)
device_list_data = validated_data.pop('device_list')
group = DeviceGroup.objects.create(**validated_data)
for device_list in device_list_data:
BaseDevice.objects.create(group=group, **device_list)
return group
class DeviceGroupAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
def get_object(self, user, token):
try:
return BaseDevice.objects.filter(owner=user).get(token=token)
except ObjectDoesNotExist:
return error.RequestedResourceNotFound().as_response()
def post(self, request, token=None, format=None):
device_group_instance = DeviceGroup.objects.get(token=token)
for device_token in request.data['devices']:
device = Device.objects.get(token=device_token, owner=request.user)
device.group = device_group_instance
这是我的api设计
{
"data":[
{
"id":1,
"name":"Home",
"device_list":[
{
"id":"481cfef5a4884e52a63d135967fbc367",
"name":"Oxygen Provider"
},
{
"id":"7eb006d6db50479aa47f887da0d4f10e",
"name":"Fan Speed"
}
]
},
{
"id":2,
"name":"Business",
"device_list":[
]
}
]
}
更新
url(r'^device_group/(?P<token>[0-9a-f]+)/add$', DeviceGroupAPIView.as_view(), name='device_group'),
答案 0 :(得分:1)
我已经改变了你的代码
class BaseDevice(PolymorphicModel):
name = models.CharField(max_length=250, blank=False, null=False)
group = models.ForeignKey('DeviceGroup', related_name="groups", null=True, blank=True)
class Device(BaseDevice):
description = models.TextField(blank=True, null=True)
class DeviceGroup(models.Model):
name = models.CharField(max_length=250, blank=False, null=False)
class DeviceIdSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source='token', format='hex', read_only=True)
# token does not exist in your model so this will not be included
class Meta:
model = Device
# id is the token of the device and name is the name of the device
fields = ('id', 'name')
class DeviceGroupSerializer(serializers.ModelSerializer):
device_list = DeviceIdSerializer(read_only=False, many=True, required=False, source="groups")
class Meta:
model = DeviceGroup
# name is the name of group created and device_list is the list of devices with id(token) and device name
fields = ('id', 'name', 'device_list')
def create(self, validated_data):
print ('validated_data', validated_data)
device_list_data = validated_data.pop('groups', [])
# notice that I pop 'groups' because validation changes the input data
# to match the field names
# Also since it is not required I've added a default value
group = DeviceGroup.objects.create(**validated_data)
devices = [BaseDevice(group=group, **device_list) for device_list in device_list_data]
BaseDevice.objects.bulk_create(devices)
# Use bulk create when you have to create multiple objects
# It hits the db only once instead of multiple times
return group
class DeviceGroupAPIView(ModelViewSet):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = DeviceGroupSerializer
queryset = DeviceGroup.objects.all()
# Although I have used ModelViewSet, you could use any other one
# I used this so that I don't need to write the code for create,
# update, delete or list
# urls.py
router = routers.DefaultRouter()
router.register(r'device_group', DeviceGroupAPIView, base_name='device_group')
# this gives the following urls
# /device_group/ POST to create, GET to list
# /device_group/(?<pk>\d+)/ GET to retrieve single DeviceGroup, PATCH/PUT to update it, and DELETE to delete it
这是用于创建带有一堆设备的新DeviceGroup的POST的JSON结构
{
"name":"Group Name",
"device_list":[
{
"name":"Device 1"
},
{
"name":"Device 2"
},
{
"name":"Device 3"
}
]
}
希望这有帮助
此外,您应该阅读有关Django-Rest-Framework
的更多信息