【问题标题】:Unable to join two tables with django rest framework无法使用 django rest 框架连接两个表
【发布时间】:2020-06-02 13:09:43
【问题描述】:

我正在尝试加入两个表并将它们序列化为 API。我参考了 Django rest 框架的文档并尝试了一个代码。它没有用。即使尝试了这么多次也无法解决问题。我正在尝试获取像

这样的 JSON 文件
{
'album_name': 'The Grey Album',
'artist': 'Danger Mouse',
'tracks': [
    {'order': 1, 'title': 'Public Service Announcement'},
    {'order': 2, 'title': 'What More Can I Say'},
    {'order': 3, 'title': 'Encore'},
    ...
  ],
}

但我得到的是

{
'album_name': 'The Grey Album',
'artist': 'Danger Mouse',
}

这是我正在使用的模型文件

Model.py

from django.db import models
from django.contrib.auth.models import User



STATUS_CHOICE = (
    ('simple', 'simple'),
    ('intermediate', 'intermediate'),
)

class Quiz(models.Model):
    quiz_name = models.CharField(max_length=1000)
    video_id = models.ForeignKey("youtube.Youtube",  on_delete=models.CASCADE)
    questions_count = models.IntegerField(default=0)
    description = models.CharField(max_length=70, null=True)
    created = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField()
    pass_mark = models.IntegerField()
    class Meta:
        ordering = ['created']
    def __str__(self):
        return self.quiz_name

class Category(models.Model):
    category = models.CharField(max_length=20, choices=STATUS_CHOICE, default='simple')
    quiz_id = models.ForeignKey(Quiz, on_delete=models.CASCADE)
    def __str__(self):
        return self.category

class Questions(models.Model):
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
    question = models.CharField(max_length=1000)
    mark = models.IntegerField()
    def __str__(self):
        return self.question

class Choice(models.Model):
    question = models.ForeignKey(Questions, on_delete=models.CASCADE)
    choice_1 = models.CharField(max_length=1000)
    choice_2 = models.CharField(max_length=1000)
    choice_3 = models.CharField(max_length=1000)
    choice_4 = models.CharField(max_length=1000)
    answer = models.CharField(max_length=1000, default=choice_1)

    def __str__(self):
        return self.answer

Serializer.py

from rest_framework import  serializers
from rest_framework.permissions import IsAuthenticated   
from .models import Category, Quiz, Questions, Choice
from django.contrib.auth import authenticate
from django.contrib.auth.hashers import make_password


class QuizSerializer(serializers.ModelSerializer):
    class Meta:
        model = Quiz
        fields = '__all__'

class QuestionsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Questions
        fields = '__all__'

class ChoiceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Choice
        fields = '__all__'

class CategorySerializer(serializers.ModelSerializer):
    quiz_name =  QuizSerializer(read_only=True)
    class Meta:
        model = Category
        fields = ['id','category','quiz_name']

View.py

from rest_framework import generics, permissions, mixins
from rest_framework.response import Response
from .serializer import CategorySerializer
from .models import Category


class ViewQuiz(generics.ListCreateAPIView):
    permission_classes = [
        permissions.AllowAny,
    ]
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    def list(self, request):
        queryset = self.get_queryset()
        serializer = CategorySerializer(queryset, many=True)
        print(serializer.data)
        return Response(serializer.data)

【问题讨论】:

    标签: django django-models django-rest-framework


    【解决方案1】:
    class CategorySerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Category
            fields = ['id','category','quiz_id']
    
        def to_representation(self, instance):
           response = super().to_representation(instance)
           response['quiz_id'] = QuizSerializer(instance.quiz_id).data
           return response
    

    这将产生您想要的结果,我对序列化程序表示数据的方式进行了更改。我的一些序列化程序也在做同样的事情,但我的观点与你的有点不同。

    【讨论】:

    • 给出错误“django.core.exceptions.ImproperlyConfigured: Field name quiz_name is not valid for model Category.”
    • 我修改了一下,是因为你的模型Category没有字段名quiz_name,我查了一下,名字是quiz_id
    【解决方案2】:

    看起来您正在尝试在测验中连载问题。 为此,您需要: 1. 在Questions 模型中,在测验字段中包含related_name

    class Questions(models.Model):
        quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE, related_name="questions")
        question = models.CharField(max_length=1000)
        mark = models.IntegerField()
    
        def __str__(self):
            return self.question
    
    1. QuizSerializer 中包含questions 字段并将许多设置为True:
    class QuizSerializer(serializers.ModelSerializer):
        questions = QuestionsSerializer(source="questions", many=True)
    
        class Meta:
            model = Quiz
            fields = ("questions", ... other needed fields)
    
    1. QuizSerializer 中包含source 属性在CategorySerializer 中:
    class CategorySerializer(serializers.ModelSerializer):
        quiz_name = QuizSerializer(read_only=True, source="quiz_id")
    
        class Meta:
            model = Category
            fields = ['id', 'category', 'quiz_name']
    

    您的测验未序列化,因为表中类别和测验之间的关系称为quiz_id,但您的字段称为quiz_name,因此框架不知道应该在哪里进行测验,因为它正在查看@987654333 @ 不存在的关系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-24
      • 2017-01-29
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      • 2015-07-14
      • 2021-11-21
      相关资源
      最近更新 更多