2017-12-26 5 views
0

Ich verwende Django Rest Framework in meiner App, und ich muss neue Modellinstanzen erstellen, die Fremdschlüssel enthalten. Diese verweisen auf vorhandene Objekte in einer anderen Tabelle, daher möchte ich keine neuen Instanzen dieser Fremdobjekte erstellen. Auch kann ich nicht auf diese Objekte über ihre Primärschlüssel zugreifen, da diese Informationen nicht übermittelt werden (ich muss auf bestimmte Felder filtern, die sind enthalten in der POST Anfrage).Django REST Framework Serializer - Zugriff auf vorhandene Fremdschlüssel

Wie mache ich das? This Frage scheint das gleiche Problem zu adressieren, obwohl es mir nicht klar ist, dass die akzeptierte Antwort tatsächlich das Problem löst. Angenommen, ich habe zwei Modelle, Category und Item, mit einem ForeignKey Feld in der zweiten Angabe der Kategorie:

class Category(models.Model): 
    name = models.TextField() 
    format = models.TextField() 
    page = models.IntegerField(default=1) 
    order = models.IntegerField(default=1) 

class Item(models.Model): 
    username = models.TextField() 
    title = models.TextField() 
    category = models.ForeignKey('Category', null=True) 
    data = JSONField(null=True, blank=True) 

Der Körper des POST Anfrage besteht aus einer JSON Nutzlast, mit der Kategorie als ein Objekt definiert spezifiziert das Format , Seite und Auftragsfelder:

POST /api/items 
{ 
    "username" : "test", 
    "title" : "foo", 
    "category" : { 
    "format" : "A", 
    "page" : 2, 
    "order" : 1 
    }, 
    "data" : [1,2,3,4,5] 
} 

Dann nehme ich an, ich könnte meine Item Serializer wie folgt definieren, zwingende create so, dass es die richtige Category Beispiel durch Filterung auf die entsprechenden Felder abruft, und in die zurück Item Instanz Einstellung:

class ItemSerializer(serializers.ModelSerializer): 
    category = CategorySerializer() 
    data = serializers.ListField() 

    class Meta: 
     model = Item 
     fields = ('username', 'title', 'category', 'data') 

    def create(self, validated_data): 
     category_dict = validated_data.pop('category') 
     item = Item.objects.create(**validated_data) 
     format = category_dict.format 
     page = category_dict.page 
     order = category_dict.order 
     item.category = Category.objects.get(format=format, page=page, order=order) 
     return item 

Ist dies der richtige Weg, es zu tun?

+1

ja es ist der richtige Weg es zu tun. Sie müssen auch einen Namen geben. Wenn also eine Kategorie mit diesen Details nicht existiert, können Sie auch eine neue Kategorie erstellen. Falls Sie sicher sind, dass Sie die richtige Kategorie angeben, die bereits verfügbar ist, dann ist dies der richtige Weg. –

Antwort

1

Es wird wie sein

try: 
    category = Category.objects.filter(format=format, page=page, order=order) 
except Category.DoesNotExist: 
    # either make it None or create new category, depends on your requirement 
    category = None 
    # or create new category 
except Category.MultipleObjectsReturned: 
    category = category.first() # it depends on your requirement 
item.category = category 
1

Mindestens ein Fehler ist, Sie get zu bekommen nur eine Kategorie, wie Sie Artikel der Kategorie statt Verwendung filter zu bekommen queryset verwenden sollten.

class ItemSerializer(serializers.ModelSerializer): 
    category = CategorySerializer() 
    data = serializers.ListField() 

    class Meta: 
     model = Item 
     fields = ('username', 'title', 'category', 'data') 

    def create(self, validated_data): 
     category_dict = validated_data.pop('category') 
     item = Item.objects.create(**validated_data) 
     format = category_dict.format 
     page = category_dict.page 
     order = category_dict.order 
     try: 
      item.category = Category.objects.get(format=format, page=page, order=order) 
     except Category.DoesNotExist: 
      pass 
     except Category.MultipleObjectsReturned: 
      pass 
     return item 
Verwandte Themen