我试图通过将<video id="really-cool-video" class="video-js vjs-default-skin" controls
preload="auto" width="640" height="264" poster="really-cool-video-poster.jpg"
data-setup='{ "autoplay": true, "preload": "auto"}'>
传递给序列化程序来序列化对象列表。如果我传递实例而不是没有many=True
的列表,则序列化程序可以正常工作。我仍然试图了解序列化程序如何工作,但无法调试此问题。我正在使用DRF 3.3.0
查看(下面第3行的错误)
many=True
串行器:
class BubbleExamView(object):
def get_context_data(self, **kwargs):
sections = self.data.exam.section_set.all()
if serializers.TakeSectionSerializer(
sections, self.data.user.id, many=True).is_valid(raise_exception=True):
sections_json = renderer.render(serializers.TakeSectionSerializer(
sections, self.data.user.id, many=True).data)
context = {
'exam': self.data.exam,
'sections_json': sections_json,
'student': self.data.user,
'course': self.data.exam.course,
}
context.update(kwargs)
return super(BubbleExamView, self).get_context_data(**context)
....
....
回溯
class FullAssetSerializer(serializers.ModelSerializer):
image = serializers.SerializerMethodField('get_image_url')
def get_image_url(self, asset):
if asset.image:
return default_storage.url(asset.image.name)
class Meta:
model = models.Asset
fields = ('id', 'asset_type', 'text', 'image',)
class FullQuestionAssetSerializer(serializers.ModelSerializer):
asset = FullAssetSerializer()
class Meta:
model = models.QuestionAsset
fields = ('id', 'order', 'asset')
class StubbedSectionSerializer(serializers.ModelSerializer):
"""Serialize a section object, without any of the assets or questions"""
class Meta:
model = models.Section
fields = ('id', 'exam', 'name', 'number', 'duration', 'break_duration')
class TakeSectionSerializer(StubbedSectionSerializer):
"""Serialize a section object, along with all the assets and questions that are contained in the section
in order to display it to a student taking the exam"""
class Meta(StubbedSectionSerializer.Meta):
fields = StubbedSectionSerializer.Meta.fields + ('assets', 'examquestions')
examquestions = serializers.SerializerMethodField('get_exam_questions')
assets = FullAssetSerializer(many=True)
def __init__(self, section, user_id, **kwargs):
super(TakeSectionSerializer, self).__init__(section, **kwargs)
self.user_id = user_id
def get_exam_questions(self, section):
examquestions = section.examquestion_set.all()
kwargs = {
'exam_question__section_id':section.id,
'exam_response__user_id':self.user_id,
}
choiceresponses = models.ChoiceQuestionResponse.objects.filter(**kwargs)
textresponses = models.TextQuestionResponse.objects.filter(**kwargs)
for eq, response in utils.zip_responses(
examquestions,
itertools.chain(choiceresponses, textresponses),
'exam_question_id'
):
eq.response = response
return ExamQuestionSerializer(examquestions, many=True).data
答案 0 :(得分:2)
您只是将用户ID作为数据传递给序列化程序,并且序列化程序正在抱怨,因为这绝对不是正确的数据格式。
if serializers.TakeSectionSerializer(
sections, self.data.user.id, many=True).is_valid(raise_exception=True):
序列化程序需要一个完整的数据字典(键是序列化程序字段),如果指定many=True
,它们需要一个字典列表。您只传递单个值,即用户的ID,而不是字典列表。因此,DRF抱怨只给出一个整数而不是一个项目列表。
我建议looking at the DRF tutorial更好地了解序列化的工作原理。
答案 1 :(得分:0)
我不会因此而受到赞扬,但这是有效的答案,并由DRF人员解决他们的github问题。
“我检查了DRF中的Serializer代码,我们覆盖了__new__
,这意味着你的__init__
构造函数覆盖是无用的(之前发生了魔法)。这就是代码行在DRF来源中
我建议你删除TakeSectionSerializer中的__init__
。相反,您应该在上下文TakeSectionSerializer(sections, context={'user_id': self.user.id}, many=True)
中传递self.user.id并相应地修改TakeSectionSerializer代码。
如果您不知道如何获取上下文以便在get_exam_questions中使用它,您可能需要查看我们的“包含额外上下文”示例。基本上self.context['user_id']
应该有效。
这肯定会解决你的问题。“