2013-12-10 90 views
5

让我们从django文档中使用的有关使用through参数的M2M关系的模型开始,指出将充当中介的模型。如何在django-rest中使用M2M关系

class Person(models.Model): 
    name = models.CharField(max_length=128) 

    def __unicode__(self): 
     return self.name 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person, 
            through='Membership') 

    def __unicode__(self): 
     return self.name 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    date_joined = models.DateField() 

    class Meta: 
     ordering = ['date_joined'] 

现在假设我想有一个休息读写视图也包含每组里面所有的人,通过场date_joined下令集团模式。 JSON序列化,我想获得的是以下(成员与它们的ID只描述):

{ 
    "id": 1, 
    "name": "U2", 
    "members": [ 
     20, 
     269, 
     134, 
     12, 
    ] 
} 

我写了一个串行:

class GroupSerializer(serializers.ModelSerializer): 
    members = serializers.SlugRelatedField(source='membership_set', 
              many=True, 
              read_only=False, 
              slug_field='person_id', 
              required=True) 

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

而对于读操作,它工作得很好,它不写作。我应该如何定义串行因此,鉴于上述定义的序列化,它将被继续:

  1. 创建组对象
  2. 添加每个工作组成员(通过创建一个成员对象)

回答

2

here您可以看到您正在尝试执行的操作仅适用于读取操作。这是DRF的一个常见问题,正如其创建者Tom Christie在this评论中所述。

另外,对于您想要的JSON序列化,建议使用与PK相关的字段,如here所示,尽管这不会帮助创建组对象并添加成员。你将不得不自己写代码。

希望这会有所帮助。

编辑通过创建成员将每个人的集团

代码片段:

def post_save(self, obj, created=False): 
    # obj represents the Group object 
    if created: 
     # Test to see if the Group was successfully created 
     members = self.request.DATA.get('members', None) 
     if members not None: 
      for id in members: 
       person = Person.objects.get(id=id) 
       membership, m_created = Membership.objects.get_or_create(person=person, group=obj) 
       # Here you can use m_created to see if the membership already existed and to do whatever else you need. 

此实现假定您已经声明了与auto_now date_joined。如果没有,你也应该把它作为参数传入。

+0

非常感谢您给我的明确答案,以及文档相关部分的链接或作者对该问题的回答。这是一个可惜的,我试图做的并不是非常支持这个框架。你能否建议我通过自己编写代码来完成任务?什么是正确的方法?再次感谢你! – Dragster

+0

我很高兴我可以帮助:)至于创建部分,您可以在两个位置执行此操作:在** post/create **方法或** post_save **方法中。我建议在** post_save **中完成它,因为这意味着您允许框架创建Group对象,剩下要做的就是添加成员。我将用一小段代码片段编辑我的答案,以了解如何使用此方法。 – AdelaN

+0

非常感谢,您的支持非常感谢! – Dragster