2016-07-29 7 views
0

Ich erstelle eine API und versuche herauszufinden, wie alle Daten aus meinem Shipping Modell in die GET-Methode zurückgeben, aber immer noch die PK durch die POST-Methode senden.Django Rest Framework GET alle Daten, aber POST pk

Ich lese bereits einige Lösungen here und here, aber es löste mein gesamtes Problem nicht, irgendwann brauche ich zwei verschiedene Verhaltensweisen von meiner API, wo der Client nur den Primärschlüssel senden muss.

Ich erwarte, dass dies in meinem GET /Shipping:

[{ 
    "pk": 1, 
    ... 
    "city_of_origin": { 
     "pk": 1, 
     "name": "San Francisco", 
     "state": { 
      "pk": 1, 
      "initial": "CA", 
      "name": "California" 
     } 
    }, 
    "destination_cities": [ 
     { 
      "pk": 2, 
      "name": "San Jose", 
      "state": { 
       "pk": 1, 
       "initial": "CA", 
       "name": "California" 
      } 
     },{ 
      "pk": 3, 
      "name": "Los Angeles", 
      "state": { 
       "pk": 1, 
       "initial": "CA", 
       "name": "California" 
      } 
     } 
    ] 
}] 

Und dies in meinem POST:

[{ 
    "pk": 1, 
    ... 
    "city_of_origin": 1, 
    "destination_cities": [2, 3] 
}] 

Ich habe versucht, meine ändern serializers.py:

class StateSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = State 

class CitySerializer(serializers.ModelSerializer): 
    state = StateSerializer() 

    class Meta: 
     model = City 

class ShippingSerializer(serializers.ModelSerializer): 
    city_of_origin = CitySerializer() 
    destination_cities = CitySerializer(many=True) 

    class Meta: 
     model = Shipping 

Es funktionierte gut, alle Daten zurückgebend, jedoch änderte es alle meine API-Wurzelformen und zwang, eine Stadt und einen Zustand n zu verursachen zu meinem Versand, wo ich ein Dropdown-Menü mit den Städten hatte, bevor ich meinen Serializer änderte. Die Ausstellung dieses Drop-down ist jedoch das Verhalten, das ich auf dem POST-Formular erwarte.

Hier ist es meine models.py:

class Shipping(models.Model): 
    city_of_origin = models.ForeignKey(City, related_name='origin', default=None) 
    destination_cities = models.ManyToManyField(City, related_name='destiny', default=None) 

class City(models.Model): 
    name = models.CharField(blank=False, null=True, max_length=255) 
    state = models.ForeignKey(State, null=True) 

    def __str__(self): 
     return self.name 

class State(models.Model): 
    name = models.CharField(blank=False, null=True, max_length=255) 
    initial = models.CharField(max_length=2, blank=False, null=True) 

    def __str__(self): 
     return self.name 

Ich möchte vorher alle Hilfe, ihr danken, mich zur Verfügung stellen können.

EDIT: ich Django Rest 1.9.5 und Django Framework 3.3.3

Antwort

1

Wenn get und post durch den gleichen Rest api Ansicht behandelt werden mit bin, ich glaube, Sie so etwas wie ein ViewSet verwenden (oder eine entsprechend gemischte GenericAPIView). Ihr ViewSet wird einen anderen Serializer zum Abrufen und zum Posten verwenden.

für das Erhalten/Auflistung finden Sie die, die Sie bereits erstellt verwenden (wir es umbenennen):

class ShippingGetSerializer(serializers.ModelSerializer): 
    city_of_origin = CitySerializer() 
    destination_cities = CitySerializer(many=True) 

    class Meta: 
     model = Shipping 

für die Buchung:

class ShippingPostSerializer(serializers.ModelSerializer): 
    city_of_origin = serializers.PrimaryKeyRelatedField() 
    destination_cities = serializers.PrimaryKeyRelatedField(many=True) 

    class Meta: 
     model = Shipping 

Ihre Viewset eine Definition von get_serializer() wie diese haben würde:

class ShippingViewSet(viewsets.ModelViewSet): 

    queryset = Shipping.objects.all() 

    def get_serializer_class(self): 
     if self.request.method == 'POST': 
      return ShippingPostSerializer 
     return ShippingGetSerializer 

Wenn Sie zwei verschiedene Ansichten für die get und pos verwenden t Einsprungspunkt, erstellen Sie jedem die Zuordnung der serializer_class Klassenattribut zu den entsprechenden Serialisierer wie ich schrieb.

+0

Es tut mir leid, ich habe vergessen, es zu erwähnen, aber ich habe diese Art von ViewSet mit 'ModelViewSet' und Standard-Deklarationen von Queryset und Serializer-Klasse verwendet. Deine Lösung hat sehr gut funktioniert, ich bin sehr dankbar, danke! – moshemeirelles