首页 > 解决方案 > Django Rest Framework API,调用 get_queryset 两次

问题描述

我正在开发一个 API,在收到请求时,我将创建一些记录,然后返回结果。所有这些都按预期工作,但 get_queryset 被调用了两次,并且对象被创建了两次。语句 print("create quiz") 执行两次。我究竟做错了什么?请提供任何帮助。

class CreateQuiz(generics.ListCreateAPIView):    
    serializer_class = QuizSerializer
    
    def get_queryset(self):
        classId = self.kwargs.get('classId',None)
        subject = self.kwargs.get('subject',None)
        category = Category.objects.filter(class_id=classId,category=subject).values_list('id',flat=True)[0]        
        subcategory=self.kwargs.get('chapter',None)
        total_marks = 30
        questionIDs = Question.objects.raw('''somesql''',params=[category,subcategory,total_marks,category,subcategory,total_marks])
        
        questions= MCQuestion.objects.filter(question_ptr_id__in=questionIDs).prefetch_related('answer_set__question')
        essayquestions= Essay_Question.objects.filter(question_ptr_id__in=questionIDs)
        
        user = User.objects.get(id=1)
        
        if MCQuestion.objects.filter(question_ptr_id__in=questionIDs).prefetch_related('answer_set__question').exists():
            print("create quiz")
            quiztitle ="Practice"
            quiz = Quiz()
            quiz.category_id = category
            quiz.title = quiztitle
            quiz.owner= user
            quiz.single_attempt = False
            quiz.durationtest="10:00"
            quiz.random_order=True
            subcatdescr = SubCategory.objects.filter(id=subcategory).values_list('sub_category',flat=True)[0]
            subcatprint=" "
            if subcatprint==" ":
                subcatprint = subcatdescr
            else:
                subcatprint = subcatprint+" , "+subcatdescr
            quiz.title = "Practice Exam : "+ quiz.category.class_id.classVal +" "+quiz.category.category +" ("+subcatprint+") "
            quiz.save()
                                           
            quizid = Quiz.objects.filter(id=quiz.id).values_list('id',flat=True)[0]      
            
            try:
                with connection.cursor() as cursor:
                        cursor.execute("INSERT INTO quiz_subcategory_quiz(subcategory_id,quiz_id) VALUES (%s,%s)",(subcategory,quiz.id,))                      
            except Exception:
                    print("Did not create quiz subcategory")
            
            category_description = Category.objects.filter(id=category)
            
            for obj in questionIDs:
                print(quiz.id)
                with connection.cursor() as questioncursor:                                
                    questioncursor.execute("INSERT INTO quiz_question_quiz(question_id,quiz_id) VALUES (%s,%s)",(obj.id,quiz.id,))
            
        else:
            response = JsonResponse({"error": "there was an error"})
            response.status_code = 403 # To announce that the user isn't allowed to publish
               
        return Quiz.objects.filter(id=quizid)  
             

插入数据的测验模型。

class Quiz(models.Model):

    title = models.CharField(
        verbose_name=_("Title"),
        max_length=300, blank=False)

    url = models.SlugField(
        max_length=60, blank=False,
        help_text=_("a user friendly url"),
        verbose_name=_("user friendly url"),default=uuid.uuid4)

    category = models.ForeignKey(
        Category, null=True, blank=True,
        verbose_name=_("Category"), on_delete=models.CASCADE)   
    
    DIFFICULTY_LEVEL=[
        ('1','Beginner'),
        ('2','Intermediate'),
        ('3','Advanced'),
        ('4','Exppert'),
    ]

    difficulty = models.CharField(
        max_length=2,
        choices=DIFFICULTY_LEVEL,
        default=2,
    )
    
    durationtest = models.CharField(max_length=6,blank=True,null=True)
    owner = models.ForeignKey(User,  null=True, blank=True, on_delete=models.SET_NULL)
    created_at = models.DateTimeField(auto_now_add=True,blank=True,null=True,)
      

根据 ClassID、主题、类别,提取问题列表并创建测验。问题被添加到 quiz_question_quiz 模型中(多对多关系)。

标签: djangodjango-rest-frameworkdjango-viewsdjango-serializer

解决方案


Ifget_queryset被调用两次 - 这并不意味着它被评估两次,所以一般来说它是安全的。如果您真的需要知道调用get_queryset方法是什么,您可以打印当前调用堆栈并查看:

import traceback
...
    def get_queryset(self):
        for line in traceback.format_stack():
            print(line.strip())
        ...

推荐阅读