2015-02-24 61 views
7

我想在DRF 3中創建一個參考應用程序來演示可以創建/更新模型的嵌套序列化程序。在嘗試創建嵌套模型時,**之後具有「* create()參數炸彈的示例代碼必須是映射,而不是列表*」。我也不清楚如何處理.update(),因爲在某些情況下,我只是想建立更多的關係(人員)。DRF 3 - 創建多對多更新/創建序列化雖然表

樣品型號:

from django.db import models 
class Person(models.Model): 
    name = models.CharField(max_length=128) 
class Group(models.Model): 
    name = models.CharField(max_length=128) 
    persons = models.ManyToManyField(Person, through='Membership') 
class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 

而串行和viewsets:

from rest_framework.serializers import ModelSerializer 
from rest_framework.viewsets import ModelViewSet 
from app.models import Group, Person 
class PersonSerializer(ModelSerializer): 
    class Meta: 
     model = Person 
class GroupSerializer(ModelSerializer): 
    persons = PersonSerializer(many=True) 
    def create(self, validated_data): 
     persons = validated_data.pop('persons') 
     group = Group.objects.create(**validated_data) 
     if persons: # Bombs without this check 
      Person.objects.create(group=group, **persons) # Errors here 
     return group 
    class Meta: 
     model = Group 

class PersonModelViewSet(ModelViewSet): 
    serializer_class = PersonSerializer 
    queryset = Person.objects.all() 

class GroupModelViewSet(ModelViewSet): 
    serializer_class = GroupSerializer 
    queryset = Group.objects.all() 

我想張貼一些JSON是插入一組兩個(相關)的人:

{ 
    "persons": [ 
     { "name" : "name 1" }, 
     { "name" : "name 2" } 
    ], 
    "name": "group name 1" 
} 

回答

6

我不知道如果有更簡單的方法,但是我設法實現這個工作的唯一方法是在組序列化器中引用「through」模型「成員資格」併爲.create()編寫自定義代碼。和.update()。這似乎是很多工作來設置M2M FK的。如果有人知道更好的方式,我很樂意聽到它。

class GroupMembershipSerializer(ModelSerializer): 
    class Meta: 
     model = Membership 
     fields = ('person',) 

class GroupCreateSerializer(ModelSerializer): 
    memberships = GroupMembershipSerializer(many=True, required=False) 

    def create(self, validated_data): 
     person_data = validated_data.pop('memberships') 
     group = Group.objects.create(**validated_data) 
     for person in person_data: 
      d=dict(person) 
      Membership.objects.create(group=group, person=d['person']) 
     return group 

    def update(self, instance, validated_data): 
     person_data = validated_data.pop('memberships') 
     for item in validated_data: 
      if Group._meta.get_field(item): 
       setattr(instance, item, validated_data[item]) 
     Membership.objects.filter(group=instance).delete() 
     for person in person_data: 
      d=dict(person) 
      Membership.objects.create(group=instance, person=d['person']) 
     instance.save() 
     return instance 

    class Meta: 
     model = Group 

class GroupCreateModelViewSet(ModelViewSet): 
    serializer_class = GroupCreateSerializer 
    queryset = Group.objects.all() 

所以你可以使用創建與相關人(S)的新組:

{ 
    "name" : "Group 1", 
    "memberships" : [ 
     { "person" : 1 }, 
     { "person" : 2 } 
    ] 
} 
+0

的手指越過了,我可以像這樣得到類似於這個用例的工作,將會回報。 – seanmus 2017-05-12 21:15:05

4

使用PrimaryKeyRelatedField此處顯示:

http://www.django-rest-framework.org/api-guide/relations/#primarykeyrelatedfield

class GroupSerializer(serializers.ModelSerializer): 
    persons = serializers.PrimaryKeyRelatedField(
     many=True, queryset=Person.objects.all()) 

    class Meta: 
     model = Group 
     fields = ('name', 'persons') 

創建每個人首先,例如。 ID爲1的人,姓名=「Bob」。身份證2,姓名=「Tim」的人。然後使用他們primary keys所以他們張貼到REST端點:

# Group create() REST endpoint data to POST 
{'name': 'my group', 'persons': [1, 2]} 

現在你已經事先建立的人,是集團的一部分。

+0

這是一個開始,但如何我在一個單一的POST創建組和人員。看起來DRF 3處理嵌套更新,我只是不夠明白的例子。 – LiteWait 2015-02-25 01:26:10

+0

你的例子不適合我。它永遠不會創建人員列表,它總是空的。 – LiteWait 2015-02-25 02:40:47

+0

@LiteWait同樣在這裏,我的manytomany列表保持爲空 – Programmingjoe 2017-09-16 23:38:19