如何组合来自两个模型的两个查询集? Django 休息框架
How to combine two querysets from two models? Django Rest Framework
我有两个模型
class Answer(models.Model):
answer = models.TextField()
created_at = models.DateTimeField(editable=False, default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
user = models.ForeignKey('users.CustomUser', on_delete=models.PROTECT)
question = models.ForeignKey('Question', on_delete=models.PROTECT)
number_of_points = models.IntegerField(default=0)
moderate_status = models.BooleanField(default=False)
和
class Question(models.Model):
question_subject = models.TextField()
question_text = models.TextField(default=None, null=True, blank=True)
slug = models.SlugField(max_length=128, unique=True, null=False, editable=False)
created_at = models.DateTimeField(editable=False, default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
user = models.ForeignKey('users.CustomUser', on_delete=models.PROTECT)
animal = models.ForeignKey('animals.Animal', on_delete=models.PROTECT)
serializers.py
class QuestionDetailSerializer(serializers.ModelSerializer):
answers = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Question
fields = '__all__'
views.py
class QuestionsDetailView(generics.ListAPIView):
queryset = Question.objects.all()
serializer_class = QuestionsSerializer
def get_queryset(self):
return super().get_queryset().filter(
id=self.kwargs['pk']
)
url.py
path('questions/<int:pk>', QuestionsDetailView.as_view()),
我想合并 2 个查询集,一个已经通过 url 中提供的 pk 过滤问题,另一个我想提供的查询集是 Answer.objects.all()。过滤器(question__id='pk')。本质上,我想显示所有问题以及特定问题的答案。
我强烈建议尽可能使用关系。
将related_name
添加到models.py
中的Answer.question
:
class Answer(models.Model):
...
question = models.ForeignKey('Question', on_delete=models.PROTECT, related_name='answers')
如果id
在序列化器中足够了,那么在serializers.py
中:
class QuestionDetailSerializer(serializers.ModelSerializer):
# this is not needed anymore: answers = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Question
fields = ['question_subject ', 'question_text', ..., 'answers`]
但是您也可以创建一个 model
的函数,您可以用类似的方式包含它:
class Question(models.Model):
...
def get_answers(self):
return [answer.answer for answer in self.answers.all()] # it will return a list of TextFields of answers
serializers.py
:
class QuestionDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = ['question_subject ', 'question_text', ..., 'get_answers`]
您不会完全组合来自不同 table 的 2 个查询集。但是你可以使用嵌套的序列化器。
class AnswerSerializer(serializers.ModelSerializer):
class Meta:
model = Anwser
fields = ['id', ...]
class QuestionDetailSerializer(serializers.ModelSerializer):
answer_set = AnswerSerializer(many=True, read_only=True)
class Meta:
model = Question
fields = ['id', ..., 'answer_set']
# OR
class QuestionDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = ['id']
def to_representation(self, instance):
data = super().to_representation(instance)
data['answers'] = AnswerSerializer(many=True, instance=instance.anwser_set.all()).data
return data
我有两个模型
class Answer(models.Model):
answer = models.TextField()
created_at = models.DateTimeField(editable=False, default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
user = models.ForeignKey('users.CustomUser', on_delete=models.PROTECT)
question = models.ForeignKey('Question', on_delete=models.PROTECT)
number_of_points = models.IntegerField(default=0)
moderate_status = models.BooleanField(default=False)
和
class Question(models.Model):
question_subject = models.TextField()
question_text = models.TextField(default=None, null=True, blank=True)
slug = models.SlugField(max_length=128, unique=True, null=False, editable=False)
created_at = models.DateTimeField(editable=False, default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
user = models.ForeignKey('users.CustomUser', on_delete=models.PROTECT)
animal = models.ForeignKey('animals.Animal', on_delete=models.PROTECT)
serializers.py
class QuestionDetailSerializer(serializers.ModelSerializer):
answers = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Question
fields = '__all__'
views.py
class QuestionsDetailView(generics.ListAPIView):
queryset = Question.objects.all()
serializer_class = QuestionsSerializer
def get_queryset(self):
return super().get_queryset().filter(
id=self.kwargs['pk']
)
url.py
path('questions/<int:pk>', QuestionsDetailView.as_view()),
我想合并 2 个查询集,一个已经通过 url 中提供的 pk 过滤问题,另一个我想提供的查询集是 Answer.objects.all()。过滤器(question__id='pk')。本质上,我想显示所有问题以及特定问题的答案。
我强烈建议尽可能使用关系。
将related_name
添加到models.py
中的Answer.question
:
class Answer(models.Model):
...
question = models.ForeignKey('Question', on_delete=models.PROTECT, related_name='answers')
如果id
在序列化器中足够了,那么在serializers.py
中:
class QuestionDetailSerializer(serializers.ModelSerializer):
# this is not needed anymore: answers = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Question
fields = ['question_subject ', 'question_text', ..., 'answers`]
但是您也可以创建一个 model
的函数,您可以用类似的方式包含它:
class Question(models.Model):
...
def get_answers(self):
return [answer.answer for answer in self.answers.all()] # it will return a list of TextFields of answers
serializers.py
:
class QuestionDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = ['question_subject ', 'question_text', ..., 'get_answers`]
您不会完全组合来自不同 table 的 2 个查询集。但是你可以使用嵌套的序列化器。
class AnswerSerializer(serializers.ModelSerializer):
class Meta:
model = Anwser
fields = ['id', ...]
class QuestionDetailSerializer(serializers.ModelSerializer):
answer_set = AnswerSerializer(many=True, read_only=True)
class Meta:
model = Question
fields = ['id', ..., 'answer_set']
# OR
class QuestionDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = ['id']
def to_representation(self, instance):
data = super().to_representation(instance)
data['answers'] = AnswerSerializer(many=True, instance=instance.anwser_set.all()).data
return data