2016-08-04 35 views
0

Ich bin neu in Django. Lesen Sie viele Möglichkeiten, um das Gleiche zu tun - aber nicht die sprichwörtliche Nadel im Heuhaufen zu finden. Eine solche Nadel ist ein einfaches "Finde oder Erstelle" -Muster für Django Rest.Django Rest ModelSerializer Suchen oder Erstellen Muster

Ich versuche ein einfaches Beispiel zu finden, wie man ein Find- oder Create-Muster für eine meiner Modelldaten mithilfe der Methoden Django Rest ModelSerializer und CreateAPIView implementieren kann. Lassen Sie mich sagen, dass ich ein Modell Location mit einem eindeutigen Feld "Adresse" habe. Ich möchte eine vorhandene Instanz zurückgeben, wenn die Adresse bereits in meiner Datenbank vorhanden ist. Wenn die Adresse nicht vorhanden ist, möchte ich einen Eintrag in der Datenbank erstellen und andere berechnete Werte für das Objekt auffüllen.

class Location(models.Model): 
    address = models.CharField(max_length=100, unique=True,) 
    thing1 = models.CharField(max_length=100, blank=True, null=True,) 
    thing2 = models.CharField(max_length=100, blank=True, null=True,) 

    def compute_things(self, address): 
     somevalue1 = ... 
     somevalue2 = .... 
     return somevalue1, somevalue2 

Nun, ich bin nicht ganz sicher, wie die Serializer und Ansicht zu schreiben, so dass:

  1. Ein neuer Standort erstellt und zurückgegeben mit allen Feldern initialisiert, wenn eine neue Adresse für gesehen das erste Mal
  2. Eine bestehende Lage, die ‚Adresse‘ in der Datenbank übereinstimmt, wird anstelle von Schritt 1
  3. zurück

Was sollte ich noch für das Modell definieren? Wie schreibe ich APIView und CreateSerializer, um das Richtige zu bekommen? Wo soll ich die compute_thing() aufrufen, um die fehlenden Felder zu füllen.

Für den Serializer:

class LocationCreateSerializer(ModelSerializer): 
    class Meta: 
     model = Location 

Und für die APIView:

class LocationCreateAPIView(CreateAPIView): 
    serializer_class = LocationCreateSerializer 
    queryset = Location.objects.all() 

Die APIView und Serializer sind oben nicht genug für das, was ich brauche. Was muss ich noch zu Model, View und Serializer hinzufügen, um das gewünschte Verhalten zu erhalten?

Ich möchte nicht, dass die Ansicht noch der Serializer Validierungsfehler für doppelte 'Adressen' zurückgibt - nur die vorhandene Instanz und kein Fehler. Es sieht so aus, als ob restore_object() veraltet ist. Gibt es einen Weg, um das zu erreichen, was ich suche?

Antwort

0

Ok folgen, dachte ich, die Antwort auf meine eigene Frage aus. Ich bin mir nicht sicher, ob das die beste Lösung ist. aber für alle, die eine Lösung braucht, hier ist das, was ich am Ende tun:

class LocationCreateAPIView(CreateAPIView): 
    serializer_class = LocationCreateSerializer 
    queryset = Location.objects.all() 

    def post(self, request, format=None): 
     address = None 
     if 'address' in self.request.data: 
      address = self.request.data['address'] 
     else: 
      return Response(status=HTTP_400_BAD_REQUEST) 

     try: 
      location = Location.objects.get(address=address) 
      serializer = self.get_serializer(location) 
      return Response(serializer.data, status=HTTP_200_OK) 
     except Location.DoesNotExist: 
      pass 

     serializer = LocationCreateSerializer(data=self.request.data) 
     if serializer.is_valid(): 
      somevalue1, somevalue2 = Location.compute_things(self, address=address) 
      if (not somevalue1) | (not somevalue2): 
       return Response(status=HTTP_400_BAD_REQUEST) 

      serializer.save(address=address, thing1=somevalue1, thing2=somevalue2) 
      return Response(serializer.data, status=HTTP_201_CREATED) 

     return Response(status=HTTP_400_BAD_REQUEST) 

Wenn Sie eine bessere Lösung haben, können Sie es schreiben. Ich würde gerne weiter lernen.

0

Sie verfehlten eine Sache, das, das

fields =("Here will be your models fields. That you want to serialize.") ist nach dem model = Location in Serializer.

Und Sie können offizielle doc von Django-REST-Framework

+0

Die Standardfelder, wenn 'fields' nicht angegeben ist, sind alle Felder. Dies wird das Problem nicht lösen. – Sunny