2016-05-27 12 views
2

Ich habe ein Modell, und eines seiner Felder bezieht sich auf eine übergeordnete Benutzerinstanz (geändert in Django-Einstellungen). Django REST Framework ModelSerializer - Objekt nicht gespeichert

Wenn ich eine POST von meinem Client durchgeführt wird, endet die Route hier am create Methode up:

class CatView(ModelViewSet): 
    authentication_classes = (authentication.TokenAuthentication,) 
    permission_classes = (permissions.IsAuthenticated,) 
    serializer_class = CatListSerializer 

    def get_queryset(self): 
     return Cat.objects.filter(owner=self.request.user).order_by('id') 

    ''' 
    def list(self, request, format=None): 
     serializer = CatGetSerializer(Cat.objects.filter(owner=request.user), context={'request': request}, many=True) 
     return Response(serializer.data) 
    ''' 

    def perform_create(self, serializer): 
     serializer.save(owner=self.request.user) 

    def create(self, request, *args, **kwargs): 
     serializer = CatPutSerializer(data=request.data) 
     if serializer.is_valid(): 
      serializer.create(serializer.data) 
      return Response(serializer.data, status=HTTP_201_CREATED) 
     return Response(serializer.errors, status=HTTP_400_BAD_REQUEST) 

Wenn ein PUT mit einem Teil-Update auf meinem Modell zu tun, es funktioniert gut. Aber das Erstellen funktioniert einfach nicht. Ich injiziere manuell die user Instanz in den Serializer und bittet sie, das Objekt zu erstellen. Dann nichts. Keine Ausnahme wird ausgelöst, es werden die richtigen Daten zurückgegeben, aber das Objekt befindet sich nicht in meiner Datenbank und wird nicht gespeichert.

Was ist das Problem hier?

EDIT:

Wenn ich hinzufüge, das owner Feld zum CatPutSerializer, öffnet es Sicherheitsprobleme, da ich weiß nicht, wie dies geändert werden, um zu verhindern, wie ich will nicht den Client sende mir welchen Benutzer zuzuweisen. Und wenn ich den Serializer bin duplizieren, um auf POST nur Anfragen verwendet werden, heißt es verfehlt das owner Feld ...

Hier ist die CatPutSerializer:

class CatPutSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Cat 
     fields = ('name', 'weight', 'sterilized', 'image', 'tag', 'dob', 'race', 'gender') 

UPDATE:

Wie vorgeschlagen, gehe ich jetzt wie folgt vor:

def create(self, request, *args, **kwargs): 
    pdb.set_trace() 
    serializer = CatPutSerializer(data=request.data) 
    if serializer.is_valid(): 
     serializer.save(owner=self.request.user) 
     return Response(serializer.data, status=HTTP_201_CREATED) 
    return Response(serializer.errors, status=HTTP_400_BAD_REQUEST) 

Obwohl dieentfernt wurdeüberschreiben.

SOLUTION:

Nach einer weiteren Untersuchung, es scheint nicht zu drf, sondern auf Django/PostgreSQL selbst, so schaute ich auf Django Modell save Methode, und es scheint, dass die Verarbeitung meiner benutzerdefinierten Bild verhindert neue Objekte erstellt werden ... geändert und jetzt funktioniert.

+0

Versuchen Sie, mit PUT zu erstellen? – slider

+0

Nein, eigentlich ist der Serializer der gleiche für PUT und POST mit partiellen und nicht partiellen Argumenten, hart sollte ich seinen Namen ändern. –

+0

Nun, es sieht ok für mich aus, haha. Können Sie bitte eine Beispielanfrage und die Antwort, die Sie erhalten, auch dann posten, wenn die Daten nicht gespeichert werden? – slider

Antwort

4

Sie scheinen sowohl create als auch perform_create zu überschreiben. Wenn Sie sich den Code für CreateModelMixin ansehen, den die ModelViewSet erbt, werden Sie feststellen, dass createperform_create aufruft, die serializer.save() aufruft. Sie rufen perform_create nicht in Ihrer create Methode auf; Sie scheinen serializer.create(...) zu rufen. Wenn Sie create überschreiben, tun Sie einfach folgendes:

def create(self, request, *args, **kwargs): 
    serializer = CatPutSerializer(data=request.data) 
    if serializer.is_valid(): 
     serializer.save(owner=self.request.user) 
     return Response(serializer.data, status=HTTP_201_CREATED) 
    return Response(serializer.errors, status=HTTP_400_BAD_REQUEST) 
+0

Danke für die Antwort! So habe ich es zuerst versucht und auch nicht funktioniert. Ich habe das 'perform_create' überschrieben. Habe ich etwas verpasst? Ich werde meinen Serializer als Bearbeitung hinzufügen. –

+0

War die gute Antwort, half mir teilweise. –

Verwandte Themen