簡體   English   中英

Django REST 框架:NOT NULL 約束失敗

[英]Django REST Framework: NOT NULL constraint failed

我知道有關於 Django Rest Framework 的答案,但我找不到解決我的問題的方法。

我在 Django REST Framework 中有以下設置:

模型.py:

class Variant(models.Model):
    variant = models.CharField(max_length=30)

class Question(models.Model):
    question = models.CharField(max_length=250)
    multiple = models.BooleanField(default=False)
    variants = models.ForeignKey(Variant, db_index=True, on_delete=models.CASCADE)
    answer = models.CharField(max_length=30)


class Quiz(models.Model):
    name = models.CharField(max_length=250)
    description = models.TextField()
    questions = models.ForeignKey(Question, on_delete=models.CASCADE)
    date_created = models.DateTimeField(auto_now=True, db_index=True)

序列化程序.py:

class VariantSerializer(serializers.ModelSerializer):
    class Meta:
        model = Variant
        fields = ['id', 'variant']


class QuestionSerializer(serializers.ModelSerializer):
    variants = VariantSerializer(many=True, read_only=True)

    class Meta:
        model = Question
        fields = ['id', 'question', 'multiple', 'variants', 'answer']

    def create(self, validated_data):
        variants_data = validated_data.pop('variants')
        question = Question.objects.create(**validated_data)

        for variant in variants_data:
            Variant.objects.create(question=question, **variant)

        return question


class QuizSerializer(serializers.ModelSerializer):
    questions = QuestionSerializer(many=True)

    class Meta:
        model = Quiz
        fields = ['id', 'name', 'description', 'date_created', 'questions']

    def create(self, validated_data):
        questions_data = validated_data.pop('questions')
        quiz = Quiz.objects.create(**validated_data)

        for question in questions_data:
            Question.objects.create(quiz=quiz, **question)

        return quiz

當我嘗試發布一些使用 JSON 文件分配的數據時:

{
    "name": "quiz",
    "description": "quiz quiz quiz",
    "questions": [
        {
            "question": "What is the weather today?",
            "multiple": false,
            "variants": [
                {
                    "variant": "cloudy"
                },
                {
                    "variant": "cold"
                }
            ],
            "answer": "cloudy"
        },
        {
            "question": "What is the weather today?",
            "multiple": false,
            "variants": [
                {
                    "variant": "cloudy"
                },
                {
                    "variant": "cold"
                }
            ],
            "answer": "cloudy"
        }
    ] }

我收到錯誤django.db.utils.IntegrityError: NOT NULL constraint failed: api_quiz.questions_id

我是這個框架的新手,我可以做什么來發布數據?

您需要更改模型,因為Quiz只能有一個Question

class Variant(models.Model):
    variant = models.CharField(max_length=30)

class Question(models.Model):
    question = models.CharField(max_length=250)
    multiple = models.BooleanField(default=False)
    variants = models.ForeignKey(Variant, db_index=True, on_delete=models.CASCADE)
    answer = models.CharField(max_length=30)
    quiz = models.ForeignKey(Question, on_delete=models.DO_NOTHING, related_name="questions") 


class Quiz(models.Model):
    name = models.CharField(max_length=250)
    description = models.TextField()
    date_created = models.DateTimeField(auto_now=True, db_index=True)

我剛剛補充說:

class Question(models.Model):
    quiz = models.ForeignKey(Question, on_delete=models.DO_NOTHING, related_name="questions") 

並刪除

class Quiz(models.Model):
    questions = models.ForeignKey(Question, on_delete=models.CASCADE)

所以現在你可以使用:

quiz = Quiz.objects.get(pk=1)
quiz.questions  # Will return all Question 

這在 django 文檔中有解釋: https : //docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/

諾塔好處:聲明時,最好的做法是從來沒有使用模型類ForeignKey使用基於字符串app.ModelName為例為您的應用程序是通話quizz_exemple使用

variants = models.ForeignKey("quizz_exemple.Variant", db_index=True, on_delete=models.CASCADE)

您必須在Question模型中添加Quiz外鍵,因為一個測驗可以有很多問題。 同樣,您必須在Variant模型中添加Question外鍵,因為一個問題可以有多個變體。 您還需要添加相關名稱,這將有助於編寫嵌套 serailizer。 此外,您必須按如下方式調整序列化程序:

模型.py

class Quiz(models.Model):
    name = models.CharField(max_length=250)
    description = models.TextField()
    date_created = models.DateTimeField(auto_now=True, db_index=True)

class Question(models.Model):
    question = models.CharField(max_length=250)
    multiple = models.BooleanField(default=False)
    answer = models.CharField(max_length=30)
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE, related_name='questions')

class Variant(models.Model):
    variant = models.CharField(max_length=30)
    question = models.ForeignKey(Question, db_index=True, on_delete=models.CASCADE, related_name='variants')

序列化程序.py

class VariantSerializer(serializers.ModelSerializer):
    class Meta:
        model = Variant
        fields = ['id', 'variant']


class QuestionSerializer(serializers.ModelSerializer):
    variants = VariantSerializer(many=True)

    class Meta:
        model = Question
        fields = ['id', 'question', 'multiple', 'variants', 'answer']


class QuizSerializer(serializers.ModelSerializer):
    questions = QuestionSerializer(many=True)

    class Meta:
        model = Quiz
        fields = ['id', 'name', 'description', 'date_created', 'questions']

    def create(self, validated_data):
        questions_data = validated_data.pop('questions')
        quiz = Quiz.objects.create(**validated_data)

        for question in questions_data:
            variants_data = question.pop('variants')
            question_instance = Question.objects.create(quiz=quiz, **question)
            for variant in variants_data:
                Variant.objects.create(question=question_instance, **variant)

        return quiz

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM