Django 序列化器返回空数组

问题描述 投票:0回答:1

我对 Python 的经验很少,也没有 Django 的经验,但我的任务是修复 Django 应用程序中的错误。

我有以下型号

`   class SurveyResponse(models.Model):
    survey = models.ForeignKey(to=Survey, on_delete=models.CASCADE, related_name="responses")
    # Don't want to clear out surveys if the mission is cleared. Still may be valuable
    mission_run = models.ForeignKey(to=MissionRun, on_delete=models.SET_NULL, blank=True, null=True,
                                    related_name="survey_responses")
    grade = models.CharField(max_length=15, blank=True, null=True)  # grade level
    gender = models.CharField(max_length=15, blank=True, null=True)  # gender selection
    race = models.CharField(max_length=50, blank=True, null=True)  # race selection
    exported_survey_file = models.ForeignKey(to="SurveyVendorFile", null=True, blank=True, on_delete=models.SET_NULL,
                                             related_name="survey_responses")
    exported_evaluator_file = models.ForeignKey(to="EvaluatorFile", null=True, blank=True, on_delete=models.SET_NULL,
                                                related_name="survey_responses")



class SurveyResponseAnswer(models.Model):
    survey_response = models.ForeignKey(to=SurveyResponse, on_delete=models.CASCADE, related_name="answers")
    survey_question = models.ForeignKey(to=SurveyQuestion, on_delete=models.CASCADE, related_name="answers")
    answers = ArrayField(models.CharField(max_length=100), null=True, blank=True)
    answer = models.CharField(max_length=100, null=True, blank=True)

    @property
    def reverse_coding(self):
        return self.survey_question.reverse_coding`

然后使用此代码序列化对 POST 请求的响应

`   class SurveyResponseViewSet(mixins.CreateModelMixin, GenericViewSet):
    queryset = app_models.SurveyResponse.objects.all()
    permission_classes = []
    serializer_class = app_serializers.SurveyResponseCreateSerializer
    
    
class SurveyResponseAnswerCreateSerializer(serializers.ModelSerializer):
    survey_question_id = serializers.IntegerField()
    answers = serializers.SerializerMethodField(required=False)

    def get_answers(self, obj):
        return obj.answers if obj.answers else []

    class Meta:
        model = app_models.SurveyResponseAnswer
        exclude = ["survey_response", "survey_question"]


class SurveyResponseCreateSerializer(serializers.ModelSerializer):
    survey_id = serializers.IntegerField()
    answers = SurveyResponseAnswerCreateSerializer(many=True)
    mission_run_id = serializers.IntegerField()

    def create(self, validated_data):
        answers = validated_data.pop("answers", [])
        survey_response = app_models.SurveyResponse.objects.create(**validated_data)
        for answer in answers:
            app_models.SurveyResponseAnswer.objects.create(survey_response=survey_response, **answer)
        return survey_response

    class Meta:
        model = app_models.SurveyResponse
        exclude = ["survey", "mission_run"]`

我的帖子正文是这样的

`   {
    "missionRunId": 22,
    "surveyId": 2,
    "answers": [
        {
            "surveyQuestionId": 40,
            "answer": "1",
            "answers": []
        },
        {
            "surveyQuestionId": 41,
            "answer": null,
            "answers": [
                "1",
                "4",
                "3",
                "5"
            ]
        },
        {
            "surveyQuestionId": 43,
            "answer": null,
            "answers": [
                "a",
                "b"
            ]
        }, ... etc`

返回的 json 数据包含所有调查问题,但对于帖子中包含多项选择“答案”的任何问题,我会在响应中返回一个空数组(答案:[])。

我怀疑问题出在

   def get_answers(self, obj): return obj.answers if obj.answers else []
代码,obj.answers 为空/空,但我不确定为什么。

到目前为止,我在谷歌上的努力没有给我带来任何结果——我想我只是缺乏足够的领域知识来理解它。同样,chatgpt 也没有引导我 - 我相信再次缺乏领域知识,我不知道 chatgpt 是否给了我垃圾输出,但到目前为止它所建议的任何内容都不起作用。

django django-serializer
1个回答
0
投票

我不确定为什么你的

obj.answers
看起来是空的,但我看到你已经定义了一个特定的序列化器来对这个特定的属性应用特定的处理。

在这种情况下,您可以在主序列化器中使用

serializers.SerializerMethodField()
直接定义方法序列化器,它将自动指向您的 getter 来获取答案。也许简化序列化器会让事情变得更清晰。

然后您可以添加调试打印,以便在这种情况下为我们提供序列化器返回的值。

class SurveyResponseCreateSerializer(serializers.ModelSerializer):
    survey_id = serializers.IntegerField()
    answers = serializers.SerializerMethodField()
    mission_run_id = serializers.IntegerField()

    @staticmethod
    def get_answers(obj):
        print(f"Debugging {obj.answers}")
        return obj.answers if obj.answers else []

    def create(self, validated_data):
        answers = validated_data.pop("answers", [])
        survey_response = app_models.SurveyResponse.objects.create(**validated_data)
        for answer in answers:
           app_models.SurveyResponseAnswer.objects.create(survey_response=survey_response, **answer)
        return survey_response

    class Meta:
        model = app_models.SurveyResponse
        exclude = ["survey", "mission_run"]`
© www.soinside.com 2019 - 2024. All rights reserved.