2017-04-26 55 views
0

我的客戶端正在向我發送帶有json數組的POST,並且正在等待具有所請求數據的完整詳細信息的響應。我對單個請求和單個響應沒有任何問題,但爲了儘量減少開銷,我想處理一個數組。POST JSON數組並獲得響應作爲JSON數組

我的models.py我的串行的

class RoFile(models.Model): 
    user = models.ForeignKey('auth.User', null=True) 
    filename = models.CharField(max_length=120, null=True) 
    deleted = models.BooleanField(default=False) 
    info = models.CharField(max_length=120, null=True) 
    md5check = models.CharField(max_length=120, null=True) 

一個嘗試:

class RoFileSerializer(serializers.ModelSerializer): 
    deleted = serializers.ReadOnlyField(required=False) 
    user = serializers.ReadOnlyField(required=False) 
    info = serializers.ReadOnlyField(required=False) 

    class Meta: 
     model = RoFile 
     fields = (
      'filename', 'md5check', 'deleted', 'user', 'info', 
     ) 

    def create(self, validated_data): 
     return RoFile(**validated_data) 
對我的看法嘗試

@api_view(['POST']) 
def rofile_detaillist(request, format=None): 
    data = JSONParser().parse(request) 
    serializer = RoFileSerializer(data=data, many=True) 
    if serializer.is_valid(): 
     json_add = [] 
     for x in serializer.validated_data: 
      try: 
       rofile = RoFile.objects.filter(md5check=x['md5check']) 
      except ObjectDoesNotExist: 
       continue 

      *invalid code here* 

     return Response(jsonarraywithallinfos) 
    else: 
     return Resonse(status=status.HTTP_400_BAD_REQUEST) 

另一種觀點認爲嘗試:

class RoFileDetailList(viewsets.ModelViewSet): 
    model = RoFile 
    serializer_class = RoFileSerializer(many=True) 

    def get_queryset(self): 
     return Rofile.objects.filter(md5check=self.request.data['md5check']) 

一個POST例如:

{"filename": "filename1.exe", "md5check": "f8541061779b1efc5c30c4783edfb8f8"}, 
{"filename": "filename2.exe", "md5check": "16cdac5eb0ec829c2e2c199488681f6e"} 

我需要什麼作爲響應回:

{"filename": "filename1.exe", "md5check": "f8541061779b1efc5c30c4783edfb8f8", user: "testuser1", deleted: "True", info: ""}, 
{"filename": "filename2.exe", "md5check": "16cdac5eb0ec829c2e2c199488681f6e", user: "testuser1", deleted: "False", info: ""} 

對不起,無效代碼的一部分,但我已經嘗試了這麼多,所以我刪除了部分(意外地)。 謝謝!

編輯:

我不需要用POST創建,我只需要檢索附加數據(該模型的其餘部分)。我不得不更改序列化程序中的創建函數,因爲我不想創建條目,我只想從數據庫中檢索與md5check關聯的數據。

感謝@ zaphod100.10 我實際的串行:

class RoFileSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = RoFile 
     fields = '__all__' 
     read_only_fields = ('deleted',) 

    def create(self, validated_data): 
     return RoFile(**validated_data) 

我的觀點:

class RoFileListDetailApi(generics.ListCreateAPIView): 
    serializer_class = RoFileSerializer 

    def get_queryset(self): 
     return RoFile.objects.filter(md5check=self.request.data['md5check']) 

    def create(self, request, *args, **kwargs): 
     serializer = self.get_serializer(data=request.data, many=True) 
     serializer.is_valid(raise_exception=True) 
     self.perform_create(serializer) 
     headers = self.get_success_headers(serializer.data) 
     return Response(serializer.data, status=status.HTTP_200_OK, headers=headers) 

我的帖子:

{"filename": "filename1.exe", "md5check": "f8541061779b1efc5c30c4783edfb8f8"}, 
{"filename": "filename2.exe", "md5check": "16cdac5eb0ec829c2e2c199488681f6e"} 

現在我的實際響應是一個列表,但只用我的POST數據而不是來自db的真實數據:

{"filename": "filename1.exe", "md5check": "f8541061779b1efc5c30c4783edfb8f8", deleted: false, info: null, user: null}, 
{"filename": "filename2.exe", "md5check": "16cdac5eb0ec829c2e2c199488681f6e", deleted: false, info: null, user: null} 

應該是:

{"filename": "filename1.exe", "md5check": "f8541061779b1efc5c30c4783edfb8f8", deleted: true, info: "some info", user: "usertest1"}, 
{"filename": "filename2.exe", "md5check": "16cdac5eb0ec829c2e2c199488681f6e", deleted: false, info: "some info2", user: "usertest2"} 

回答

0

使用本:

class RoFileSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = RoFile 
     fields = '__all__' 
     read_only_fields = ('deleted', 'user', 'info') 

class RoFileListCreateApi(generics.ListCreateAPIView): 
    serializer_class = RoFileSerializer 

    def get_queryset(self): 
     return Rofile.objects.filter(md5check=self.request.data['md5check']) 

    def create(self, request, *args, **kwargs): 
     serializer = self.get_serializer(data=request.data, many=True) 
     serializer.is_valid(raise_exception=True) 
     # override perform_create or the serializers create method for custom create logic 
     self.perform_create(serializer) 
     # assign other fields to the objs and save again 
     headers = self.get_success_headers(serializer.data) 
     return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) 

你必須要通過許多=真到串行處理名單。

覆蓋通用視圖中的perform_create方法或序列化器應用自定義創建邏輯的create方法。

編輯:

基於新的信息提供我已經改變了創建方法。

def create(self, request, *args, **kwargs): 
    serializer = self.get_serializer(data=request.data, many=True) 
    serializer.is_valid(raise_exception=True) 
    # don't create anything just insert required data 
    for rof_data in serializer.data: 
     md5check = rof_data['md5check'] 
     # code to retrieve data from db based on md5check 
     .... 
     # code to insert values in rof_data 
     rof_data['user'] = user.username 
     rof_data['deleted'] = deleted 
     rof_data['info'] = info 
    headers = self.get_success_headers(serializer.data) 
    return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) 
+0

謝謝你,我不想創建它們,因爲它們已經在數據庫中。我只需要使查詢獲得額外的數據。請參閱我的編輯。 – bingobear

+0

@bingobear我昨天更新了答案。它運作了嗎? –