python - Django REST框架:在序列化程序中获取相关模型的字段
问题描述
我是 Django Rest 框架的新手。我试图让我ListAPI
展示我Quiz
(和相关)模型的各个领域。它工作正常,除了我的attempt_number
领域。我得到了正确的查询集,但我不确定如何只获取每个查询的相关值。用户可以根据需要多次参加每个测验,我想显示每次尝试的查询集,因为分数等会有所不同。
我的模型设置如下:
class Quiz(models.Model):
title = models.CharField(max_length=15)
slug = models.SlugField(blank=True)
questions_count = models.IntegerField(default=0)
class Question(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
label = models.CharField(max_length=1000)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer = models.CharField(max_length=100)
is_correct = models.BooleanField('Correct answer', default=False)
class QuizTaker(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
correct_answers = models.IntegerField(default=0)
completed = models.BooleanField(default=False)
attempt_number = models.PositiveIntegerField(default=0)
我的序列化器ListAPI
看起来如下:
class MyQuizListSerializer(serializers.ModelSerializer):
attempt = serializers.SerializerMethodField()
# etc..
class Meta:
model = Quiz
fields = "__all__"
def get_attempt(self, obj):
try:
quiztaker = QuizTaker.objects.filter(user=self.context['request'].user,
quiz=obj)
for attempt in quiztaker:
attempt_number = attempt.attempt_number
return attempt_number
如果我这样做,我总是会得到最后一个值attempt_number
(因为循环会覆盖该值)。因此,我尝试将其附加到列表中,如下所示:
a = []
for attempt in quiztaker:
attempt_number = attempt.attempt_number
a.append(attempt_number)
return a
但是后来我得到了每个查询的尝试列表,而不是每个查询的尝试次数。即我得到以下三次(因为在这种情况下有三次尝试):
{
"id": 4,
"attempt": [
1,
2,
3
]
},
但相反,我想要的是(对于尝试 2 和 3 等也是如此):
{
"id": 4,
"attempt": 1
},
所以我试着这样做:
return a[attempt_number-1]
希望它会给我第 1 次尝试的索引零,第 2 次的索引为 1,等等。但是我仍然只是得到最后一次尝试编号(在这种情况下为 3)。我该如何解决这个问题?
我也尝试使用 aIntegerField
而不是 aSerializerMethodField
如下:
attempt = serializers.IntegerField(read_only=True, source='quiztaker.attempt_number')
但它什么也没返回。
解决方案
如果我正确理解您,您希望将尝试列表添加到每个测验对象。
{
"id": 4,
"attempts": [{
"id": 1,
"attempt_number": 1,
},
{
"id": 2,
"attempt_number": 2,
}...]
}
在这种情况下,您应该有一个单独的QuizTaker
模型序列化程序并序列化SerializerMethodField
.
class QuizTakerSerializer(serializers.ModelSerializer):
class Meta:
model = QuizTaker
fields = ('id', 'attempt_number')
class MyQuizListSerializer(serializers.ModelSerializer):
attempts = serializers.SerializerMethodField()
# etc..
class Meta:
model = Quiz
fields = "__all__"
def get_attempts(self, obj):
quiztakers = QuizTaker.objects.filter(user=self.context['request'].user,quiz=obj)
return QuizTakerSerializer(quiztakers, many=True).data
老实说,您的问题不是很清楚,这将有助于对其进行编辑并使其更清晰,从而提供您想要实现的 JSON 结构。我还怀疑您打算使用的queryset
不是ORM 对象容器的实际 Django 含义。
推荐阅读
- android - java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void android.widget.ImageView.setImageResource (int)”
- vue.js - Vue 计算属性没有像我预期的那样重新计算
- c++11 - 使用 Boost.Asio,如果没有 IO 事件,是否可以添加一个每次事件循环迭代执行一次的处理程序?
- xslt - 结果树片段背后的基本原理是什么?
- node.js - Sequelize 不创建 hasMany 关联,但在 DB 中定义了外键
- python - 如何在 Python 中解决这个猜谜游戏问题?
- python - 单元 LSTM 中的 Keras Gates
- javascript - 如何在javascript函数之外获取数据
- z3 - 什么是地图[f]
- html - 用另一个图像更改站点范围的横幅图像?