2017-03-02 16 views
0

デバイスグループとデバイス用の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": [] 
     } 
    ] 
} 

UPDATE

URL(R '^ device_group /(?P [0-9A-F] +)/ $を追加'、DeviceGroupAPIView.as_view()、NAME = '装置_group ')、

+1

Django-Rest-Frameworkについては、グループ&ドを作成しないまで読んでください。また

を支援します正しく悪いですか?エラーはスローされますか?あなたが渡すインスタンスは、DeviceGroupかNoneであるべきですが、デバイスではありません。 –

+0

申し訳ありませんが、フォームがブラウズ可能なAPIに表示されないため、テストできませんでした。 – Serenity

+0

私は今、フォームを取得しますが、メディアタイプとコンテンツタイプのフォームが表示されます。 DeviceGroupのインスタンス?私はそれを理解していません – Serenity

答えて

1

私は、これはデバイスの束

{ 
    "name":"Group Name", 
    "device_list":[ 
     { 
     "name":"Device 1" 
     }, 
     { 
     "name":"Device 2" 
     }, 
     { 
     "name":"Device 3" 
     } 
    ] 
} 

希望と新しいDeviceGroupを作成するために、投稿するJSONの構造であるビット

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 

あなたのコードを変更しましたこれは、あなたがより

+0

あなたのソリューションに感謝します。私は最後の質問が1つあります。 DeviceGroupのインスタンスをDeviceGroupSerializerに送信して、私の投稿機能を変更するように指示しました。それはあなたが言っていることですか?私はAPIViewを使用しようとしたので、私はModelViewSetを使用したくない初心者として。私のポスト機能だけを見ていただけますか? – Serenity

+0

あなたのDeviceGroupはtokenと呼ばれるフィールドを持っていないので、それを使ってルックアップを実行することはできません。しかし、DeviceGroupオブジェクトを持っていれば、割り当て方法は十分です( '.save()')。これが初めてのDjangoプロジェクトの場合は、最初にチュートリアルを試してみてください。 –

+0

トークンフィールドはDeviceGroupにtoken = models.UUIDField(デフォルト= uuid.uuid4、一意= True、editable = False)としています。 。 – Serenity

関連する問題