未显示device_list

时间:2017-02-28 15:49:11

标签: python django django-rest-framework

我正在创建一个api,其中显示组列表以及属于该组的设备ID。例如,如果有一个名为Speedometer,Humidifier的设备,它们属于Home组,那么我的api应该包括

{
  "id": 1,
  "name": "Home"
  "device_list": [
    {
      "id": "b45c56ioxa1"
    },
    {
      "id": "h4oc2d5ofa9"
    }
  ]
},

但是我的代码在api中没有生成device_list。它只显示名称和ID

device_list是特定组中所有设备ID的列表。

这是我的代码

class DeviceIdSerializer(serializers.ModelSerializer):
    id = serializers.UUIDField(source='token', format='hex', read_only=True)
    class Meta:
        model = Device
        fields = ('id')

class DeviceGroupSerializer(serializers.ModelSerializer):
    name = serializers.StringRelatedField()
    device_list = DeviceIdSerializer(read_only=False, many=True, required=False, source="groups")
    class Meta:
       model = DeviceGroup
       fields = ('id', 'name', 'device_list')

class DevicesGroupsAPIView(APIView):
    permission_classes = (permissions.IsAuthenticated,)
    def get(self, request, format=None):
        """
            Returns a list of groups
        """
        reply = {}
        try:
            groups = DeviceGroup.objects.all()
            print ('reply', groups)
            reply['data'] = DeviceGroupSerializer(groups, many=True).data
        except:
            reply['data'] = []
        return Response(reply, status.HTTP_200_OK)

class BaseDevice(PolymorphicModel):
    # User's own identifier of the product
    name = models.CharField(max_length=250, blank=False, null=False)
    # Any device should have a owner, right from the creation
    owner = models.ForeignKey(User, blank=False, null=False)
    token = models.UUIDField(default=uuid.uuid4, unique=True, editable=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)

2 个答案:

答案 0 :(得分:2)

我尝试了相同的代码,只不过我使用models.Model作为基本模型 我第一次收到错误

  

fields选项必须是列表或元组或“所有”。得了str。   这清楚地说明了你的问题所在。
  所以我在DeviceIdSerializer

中更改了类选项
DeviceIdSerializer(serializers.ModelSerializer):
    id = serializers.UUIDField(source='token', format='hex', read_only=True)
    class Meta:
        model = Device
        fields = ('id',)

请注意,我添加了一个逗号(“,”),它使字段成为元组而不是之前的字符串。
现在我得到的数据是

{
   "id":1,
   "name":"test",
   "device_list":[
      {
         "id":"38ec7e152f9d49a38008c859a1022525"
      },
      {
         "id":"b0d799509260474cb092899ef84ce49c"
      },
      {
         "id":"e5c7cf8f9f5043c68c34c7b962569b08"
      }
   ]
}

与您正在寻找的相同......

答案 1 :(得分:1)

我认为您的序列化程序需要如下所示:

var oClient = new RestClient("http://localhost:52298/stockcontrol/availablestock");
            var oContainer =  new CookieContainer();
            var oRequest = new RestRequest();
            oRequest.Method = Method.GET;

            var oCookie = new Cookie("Jwt", sJwt) { HttpOnly = true, Expires = DateTime.Now.AddMinutes(10), Domain = "test" };

            oContainer.Add(oCookie);
            oClient.CookieContainer = oContainer;
            

            var oResponse = oClient.Execute(oRequest);

或者改变这个:

app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                Provider = new CookieAuthenticationProvider()
                {
                    OnValidateIdentity = async context =>
                    {
                        if (context?.Identity?.IsAuthenticated ?? false)
                        {
                            var accessToken = context?.Identity?.Claims?.FirstOrDefault(x => x.Type == "access_token")?.Value;
                            if (accessToken == null)
                            {
                                context?.RejectIdentity();
                            }
                            else
                            {
                                var client = new IntrospectionClient(
                                        sISUrl + "connect/introspect",
                                        sISClientName,
                                        sISClientSecret); // auth as scope, not client!
                                var validationResult = await client.SendAsync(new IntrospectionRequest()
                                {
                                    Token = accessToken
                                });

                                if (validationResult.IsError || !validationResult.IsActive)
                                {
                                    context?.RejectIdentity();
                                }
                            }
                        }
                    }
                }
            });