从django-rest框架中的ManytoMany字段中获取None类型值



我无法在序列化程序列表的ManytoMany字段中检索答案选择id或检索相反,我得到了quiz.Choice.None

我理解为什么,但如果我从序列化程序中删除answer = serializers.CharField()这一行。创建问题时出现错误:

{
"answer": [
"Incorrect type. Expected pk value, received str."
]
}

我无法从前端传递答案,我希望检索"answer": [2,3]而不是None,而且我还知道,如果我从序列化程序中删除answer = serializers.CharField(),这一行。它解决了问题,但它提出了另一个问题,即我无法通过一个尚未创建的答案选择id。这类问题的最佳解决方案是什么?我还尝试对一个空数组进行应答验证。但这根本不起作用。

{
"id": 5,
"label": "Question 1",
"answer": "quiz.Choice.None",
"explanation": "New Added fhfd",
"mode": 1,
"subtopic": 2,
"choice": [
{
"id": 5,
"option": "option 6 Edited New One",
"question": 5
},
{
"id": 6,
"option": "option 5 Hllloo Sakib",
"question": 5
}
]
}

我的型号:

# Question Mode
MODE = ((0, "Easy"), (1, "Medium"), (2, "Hard"))


class Question(models.Model):
"""Question Model"""

label = models.CharField(max_length=1024)
answer = models.ManyToManyField("Choice", related_name="quesans", blank=True)
explanation = models.TextField(blank=True)
mode = models.IntegerField(choices=MODE, default=0)
subtopic = models.ForeignKey(
"motherset.Subtopic", on_delete=models.CASCADE, related_name="question"
)
created_time = models.DateTimeField(auto_now_add=True, blank=True)

def __str__(self):
return self.label


class Choice(models.Model):
"""Question Option"""

option = models.CharField(max_length=1024)
question = models.ForeignKey(
Question, on_delete=models.CASCADE, related_name="choice", blank=True, null=True
)

def __str__(self):
return self.option

在Serializers.py中:

class ChoiceSerializer(serializers.ModelSerializer):
"""Serializers for Question Choice"""
id = serializers.IntegerField()
class Meta:
model = Choice
fields = ("id", "option", "question")

class CreateQuestionSerializer(serializers.ModelSerializer):
choice = ChoiceSerializer(many=True, partial=True)
answer = serializers.CharField()
class Meta:
model = Question
fields = ("id", "label", "answer", "explanation", "mode", "subtopic", "choice")
extra_kwargs = {"answer": {"validators": []}}
def create(self, validated_data):
"""Create Model With nested Serializer"""
choices_data = validated_data.pop("choice")
answerString = validated_data.pop("answer", [])
answer = literal_eval(answerString)
print(answer)
print(type(answer))
question = Question.objects.create(**validated_data)
for choice_data in choices_data:
choice_created = Choice.objects.create(
option=choice_data["option"], question=question
)
for choice_option in answer:
if choice_option == choice_created.option:
question.answer.add(choice_created)
question.save()
return question
def update(self, instance, validated_data):
"""Update Instance including nested serializer"""
choices_data = validated_data.pop("choice", None)
if choices_data is not None:
for choice_data in choices_data:
choice = Choice.objects.get(pk=choice_data["id"])
choice.option = choice_data["option"]
choice.save()
return super().update(instance, validated_data)

在api.py中:

class CreateQuestionView(viewsets.ModelViewSet):
serializer_class = CreateQuestionSerializer
queryset = Question.objects.all()

在axios柱体中:

{
"label": "Label q",
"explanation": "",
"answer": ["option 7","option 8"],
"mode": 1,
"subtopic": 2,
"choice": [
{
"id":3324242,
"option": "option 7"
},
{
"id":3324245,
"option": "option 8"
},
{
"id":3324248,
"option": "option 9"
}
]
}

answer由其pk而非option引用。

像下面这样的调用应该有效,您可以提交选择的PK而不是选项文本:

{
"label": "Label q",
"explanation": "",
"answer": [7, 8],
"mode": 1,
"subtopic": 2,
"choice": [
{
"id":3324242,
"option": "option 7"
},
{
"id":3324245,
"option": "option 8"
},
{
"id":3324248,
"option": "option 9"
}
]
}

更新

我将Modelviewset类更新为:

class CreateQuestionView(viewsets.ModelViewSet):
serializer_class = CreateQuestionSerializer
queryset = Question.objects.all()
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
answer = []
for ans in instance.answer.all():
answer.append(ans.id)
newDict = {}
newDict.update(serializer.data)
newDict.update({"answer": answer})
return Response(newDict)
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
newList = []
for question in serializer.data:
q = Question.objects.get(pk=question["id"])
answer = []
for ans in q.answer.all():
answer.append(ans.id)
newDict = {}
newDict.update(question)
newDict.update({"answer": answer})
newList.append(newDict)
return Response(newList)

现在一切都很顺利。感谢我自己v

相关内容

  • 没有找到相关文章

最新更新