2017-04-26 3 views
0

Mein Client sendet mir einen POST mit einem JSON-Array und wartet auf eine Antwort mit den vollständigen Details der angeforderten Daten. Ich habe keine Probleme mit einzelnen Anfragen und einzelnen Antworten, aber um den Overhead zu minimieren, möchte ich ein Array verarbeiten.POST JSON-Array und Antwort erhalten als JSON-Array

mein 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) 

einen Versuch meines Serializer:

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) 

auf try meiner Ansichten:

@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) 

eine andere Ansicht Versuch:

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

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

ein POST Beispiel:

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

, was ich als Antwort benötigen zurück:

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

Sorry für den ungültigen Code Teil, aber ich habe schon so viel versucht, so löschte ich, dass ein Teil (ausversehen). Vielen Dank!

EDIT:

Ich brauche nicht mit POST zu schaffen, ich brauche nur zusätzliche Daten (den Rest des Modells) abgerufen werden. Ich musste die Erstellungsfunktion im Serializer ändern, weil ich die Einträge nicht erstellen möchte, ich möchte nur die Daten abrufen, die mit dem MD5check von der Datenbank verknüpft sind.

dank @ zaphod100.10 meines eigentlichen Serializer:

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

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

meine Sicht:

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) 

meines Beitrag:

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

meine eigentliche Antwort ist jetzt eine Liste, aber nur mit meinen POST-Daten und nicht die echten Daten von der db:

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

sollte sein:

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

Antwort

0

Verwendung dieses:

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) 

Sie müssen nur wahr für den Umgang mit Listen an die Serializer viele = passieren.

Überschreiben Sie die Methode perform_create in der generischen Ansicht oder die Methode zum Erstellen der benutzerdefinierten Creation-Logik durch die Serializer-Methode.

EDIT:

auf der Basis neuer Informationen bereitgestellt ich die Methode erstellen geändert haben.

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

danke, ich möchte sie nicht erstellen, weil sie bereits in der db sind. Ich muss nur die Abfrage machen, um die zusätzlichen Daten zu erhalten. Bitte sehen Sie meine Bearbeitung. – bingobear

+0

@bingobear Ich habe die Antwort gestern aktualisiert. Hat es geklappt? –