Gal*_*lil 4 django django-serializer django-rest-framework
有示例如何创建像这样的可写嵌套序列化程序,然后如何序列化通用外键(此处)。
但是我找不到同时进行这两项操作的方法,即如何为通用外键字段创建嵌套的可写序列化程序。
在我的模型中,有一个Meeting模型,GenericForeignKey其可以是DailyMeeting或可以是WeeklyMeeting:
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
Run Code Online (Sandbox Code Playgroud)
然后,在我的中创建了一个自定义字段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__'
Run Code Online (Sandbox Code Playgroud)
我正在传递一个类似于以下内容的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"
}
}
Run Code Online (Sandbox Code Playgroud)
但是问题是我遇到以下错误:
AssertionError:关系字段必须提供
queryset参数,覆盖get_queryset或设置read_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
Run Code Online (Sandbox Code Playgroud)
如果验证顺利,那么您将在MeetingSerializer验证数据中创建对象,RecurringMeetingRelatedField否则将引发异常。
| 归档时间: |
|
| 查看次数: |
1173 次 |
| 最近记录: |