Django rest - 序列化嵌套对象

时间:2017-01-31 18:26:12

标签: python django serialization django-rest-framework django-serializer

我正在使用Django 1.10.5djangorestframework 3.5.3

我有两个与一对多关系相关的模型:

class Minisymposium(models.Model):
    STATUS_CHOICES = (
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('denied', 'Denied'))

    id = models.AutoField(primary_key=True)
    number = models.IntegerField(default=0, null=False)
    title = models.CharField(max_length=100, null=False)
    description = models.TextField(max_length=9000, null=False)
    status = models.CharField(max_length=100, choices=STATUS_CHOICES, null=False, default='pending')
    user = models.ForeignKey(User, null=False, related_name='user')
    corresponding_organizer = models.ForeignKey(User, null=False, related_name='corresponding_organizer')
    anticipated_abstracts = models.IntegerField(null=False)
    anticipated_attendees = models.IntegerField(null=False)
    date = models.DateTimeField(auto_now_add=True)

def __str__(self):
    return '{0}-{1}'.format(self.number, self.title)

class UnregisteredOrganizer(models.Model):
    id = models.AutoField(primary_key=True)
    first_name = models.CharField(max_length=1000, blank=False)
    last_name = models.CharField(max_length=1000, blank=False)
    email = models.EmailField(max_length=254, blank=True)
    affiliation = models.CharField(max_length=254, help_text='(institution only)', blank=True)
    phone_number = PhoneNumberField(blank=True)
    minisymposium = models.ForeignKey(Minisymposium, related_name='other_organizers')

每个型号都有一个序列化器。但问题出在Minisymposium的序列化程序上。因为我想在创建一个时发送一个UnregisteredOrganizer的ID,并在获得Minisymposium时将整个对象序列化。 正如我在ModelSerializer中看到的那样,这是不可能的:

class MinisymposiumSerializer(serializers.ModelSerializer):
    other_organizers = UnregisteredOrganizerSerializer(many=True)

    class Meta:
        model = Minisymposium
        fields = ('url', 'id', 'number', 'title', 'description', 'status', 'user', 'corresponding_organizer',
                  'anticipated_abstracts', 'anticipated_attendees', 'other_organizers', 'date')

    def create(self, validated_data):
        other_organizers = []

        if 'other_organizers' in validated_data:
            other_organizers = validated_data.pop('other_organizers')

        minisymposium = Minisymposium.objects.create(**validated_data)
        minisymposium.save()

        for organizer in other_organizers:
            UnregisteredOrganizer.objects.create(minisymposium=minisymposium, **organizer).save()

        return minisymposium

我该怎么做? 谢谢!

1 个答案:

答案 0 :(得分:2)

  

因为我想在创建一个UnregisteredOrganizer的ID时发送它,并在获得Minisymposium时将整个对象序列化。

为什么会出现这种不一致的API?

此处推荐的选项是将Minisymposium上的字段设置为read_only,但id应为read_only=False除外。

因此,您可以在获取数据时获取完整对象,并在发布/放置/修补数据时只需要id。发布JSON看起来像:

{
    ...
    "url": "whatever",
    "title": "Some nice title",
    "other_organizers": [{"id": 5}, {"id": 5123}]
}

创建代码如下:

def create(self, validated_data):
    other_organizers = validated_data.pop('other_organizers', [])

    minisymposium = Minisymposium.objects.create(**validated_data)
    minisymposium.save()

    organizers = []
    for organizer_id in other_organizers:
      organizers .append(UnregisteredOrganizer.objects.get(id=organizer_id)
    minisymposium. other_organizers = organizers

    return minisymposium