有示例如何创建类似于this的可写嵌套序列化程序,然后如何对通用外键(here)进行序列化。

但是我找不到如何同时做这两个事情,即如何为通用外键字段创建一个嵌套的可写序列化程序。

在我的模型中,有一个带有MeetingGenericForeignKey模型,可以是DailyMeetingWeeklyMeeting,例如:

class Meeting(models.Model):
    # More fields above
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    recurring_meeting = GenericForeignKey('content_type', 'object_id')

class DailyMeeting(models.Model):
    meeting = GenericRelation(Meeting)
    # more fields

class WeeklyMeeting(models.Model):
    meeting = GenericRelation(Meeting)
    # more fields

然后,我在serializers.py中创建了一个自定义字段:
class RecurringMeetingRelatedField(serializers.RelatedField):
    def to_representation(self, value):
        if isinstance(value, DailyMeeting):
            serializer = DailyMeetingSerializer(value)
        elif isinstance(value, WeeklyMeeting):
            serializer = WeeklyMeetingSerializer(value)
        else:
            raise Exception('Unexpected type of tagged object')
        return serializer.data


class MeetingSerializer(serializers.ModelSerializer):
    recurring_meeting = RecurringMeetingRelatedField()

    class Meta:
        model = Meeting
        fields = '__all__'

我正在传递一个类似于以下内容的JSON:
{
    "start_time": "2017-11-27T18:50:00",
    "end_time": "2017-11-27T21:30:00",
    "subject": "Test now",
    "moderators": [41],
    "recurring_meeting":{
        "interval":"daily",
        "repetitions": 10,
        "weekdays_only": "True"
        }
}

但是问题是我遇到了以下错误:



为什么“关系”字段必须为read_only?如果将其设置为read_only,则不会在序列化器的data中传递。

我必须提供哪种类型的查询集?

最佳答案

您还需要实现to_internal_value,并且可以仅使用普通的Field类。

from rest_framework.fields import Field

class RecurringMeetingRelatedField(Field):
    def to_representation(self, value):
        if isinstance(value, DailyMeeting):
            serializer = DailyMeetingSerializer(value)
        elif isinstance(value, WeeklyMeeting):
            serializer = WeeklyMeetingSerializer(value)
        else:
            raise Exception('Unexpected type of tagged object')
        return serializer.data

    def to_internal_value(self, data):
        # you need to pass some identity to figure out which serializer to use
        # supose you'll add 'meeting_type' key to your json
        meeting_type = data.pop('meeting_type')

        if meeting_type == 'daily':
            serializer = DailyMeetingSerializer(data)
        elif meeting_type == 'weekly':
            serializer = WeeklyMeetingSerializer(data)
        else:
            raise serializers.ValidationError('no meeting_type provided')

        if serializer.is_valid():
            obj = serializer.save()
        else:
            raise serializers.ValidationError(serializer.errors)

        return obj

如果验证顺利,那么您将在MeetingSerializer验证数据中创建对象,否则RecurringMeetingRelatedField会引发异常。

关于Django Rest框架: Writable nested serializers with Generic Foreign Key,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47477489/

10-13 05:19