首页 > 解决方案 > Django Rest Framework - 添加数据并返回

问题描述

我是 Django Rest Framework 的新手,并尝试根据请求创建添加数据并在创建后返回数据。

我的网址是path('quiz/<str:classId>/<str:subject>/<str:chapter>', CreateQuiz.as_view()),

我想使用 URL 中的参数向测验模型添加一行并返回它。我应该如何处理这个?我尝试在 get_queryset 方法中添加它,它运行了两次。这个具体问题的任何指南?请帮忙。

序列化器

class QuizSerializer(serializers.ModelSerializer):    
    #get_questions = QuestionSerializer(many=True)
    class Meta:
        model = Quiz
        fields=(
            'id',
            'title',
            'description',
            'url',
            'category',
            #'sub_category', 
            'random_order',
            'pass_mark',
            'draft',
            'durationtest',
            #'get_questions',
            #'get_max_score',
            #'questionlist',
            
        )

查看

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]        
        # chapter = self.kwargs.get('chapter',None)
        
        subcategory=self.kwargs.get('chapter',None)
        subcat = SubCategory.objects.filter(id=subcategory).values_list('sub_category',flat=True)[0]
        total_marks = 30
        questionIDs = Question.objects.raw('''somesql
                                         ''',params=[category,subcategory,total_marks,category,subcategory,total_marks])
        #
        
        # and qq.sub_category_id IN %s
        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")
                    
                    quiz = Quiz()
                    
                    quiz.category_id = category
                    quiz.title = "Practice"
                    quiz.owner= user
                    quiz.single_attempt = False
                    quiz.durationtest="10:00"
                    quiz.random_order=True
                    quiz.save()
                    
                    
                    quizid = Quiz.objects.filter(id=quiz.id).values_list('id',flat=True)[0]      
                    quiz = Quiz.objects.get(id=quiz.id)
                    quiz.title = "Practice Exam : "+ quiz.category.class_id.classVal +" "+quiz.category.category +" ("+subcat+") "
                    quiz.save()
                     
                    with connection.cursor() as cursor:
                                cursor.execute("INSERT INTO quiz_subcategory_quiz(subcategory_id,quiz_id) VALUES (%s,%s)",(subcategory,quiz.id,))
                    for obj in questionIDs:                           
                         
                        
                        if Question.objects.filter(id=obj.id,quiz__id=quiz.id).exists():
                            print("Do nothing")
                        else:
                            question = Question(id=obj.id)                        
                            question.quiz.add(quiz.id)
                            question.save()
                       
                    obj, created = UserQuiz.objects.update_or_create(
                            user_id = user.id,quiz_id=quiz.id            
                        )
                                        
                    return Quiz.objects.filter(id=quizid)
        else:
            response = JsonResponse({"error": "there was an error"})
            response.status_code = 403 # To announce that the user isn't allowed to publish
            return response    
                       
        return Quiz.objects.filter(id=quizid) 

型号

class Quiz(models.Model):

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

    description = models.TextField(
        verbose_name=_("Description"),
        blank=True, help_text=_("a description of the quiz"))

    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)   
    
    
    random_order = models.BooleanField(
        blank=False, default=False,
        verbose_name=_("Random Order"),
        help_text=_("Display the questions in "
                    "a random order or as they "
                    "are set?"))

    max_questions = models.PositiveIntegerField(
        blank=True, null=True, verbose_name=_("Max Questions"),
        help_text=_("Number of questions to be answered on each attempt."))

    answers_at_end = models.BooleanField(
        blank=False, default=False,
        help_text=_("Correct answer is NOT shown after question."
                    " Answers displayed at the end."),
        verbose_name=_("Answers at end"))

    exam_paper = models.BooleanField(
        blank=False, default=True,
        help_text=_("If yes, the result of each"
                    " attempt by a user will be"
                    " stored. Necessary for marking."),
        verbose_name=_("Exam Paper"))

    single_attempt = models.BooleanField(
        blank=False, default=False,
        help_text=_("If yes, only one attempt by"
                    " a user will be permitted."
                    " Non users cannot sit this exam."),
        verbose_name=_("Single Attempt"))

    pass_mark = models.SmallIntegerField(
        blank=True, default=0,
        verbose_name=_("Pass Mark"),
        help_text=_("Percentage required to pass exam."),
        validators=[MaxValueValidator(100)])

    success_text = models.TextField(
        blank=True, help_text=_("Displayed if user passes."),
        verbose_name=_("Success Text"))

    fail_text = models.TextField(
        verbose_name=_("Fail Text"),
        blank=True, help_text=_("Displayed if user fails."))

    draft = models.BooleanField(
        blank=True, default=False,
        verbose_name=_("Draft"),
        help_text=_("If yes, the quiz is not displayed"
                    " in the quiz list and can only be"
                    " taken by users who can edit"
                    " quizzes."))
    
    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,)
    history = HistoricalRecords()
         
 

标签: djangoapidjango-rest-frameworkdjango-views

解决方案


你想要达到的目标有很多困惑。该get_queryset方法旨在过滤您要发送的数据。在您的情况下,它只会指示当您发送 GET 请求(列表)时将发送哪些测验实例。

现在,对于您想要做的事情,绝对不推荐发送 POST 请求并从 URL 参数创建实例。您必须通过请求的数据部分发送信息。无论如何,在这两种情况下,您都需要覆盖视图的 create 方法。

class CreateQuiz(generics.ListCreateAPIView):
    serializer_class = QuizSerializer
            
    def get_queryset(self):
    # return a queryset here, but don't create anything !

    def create(self, request, *args, **kwargs):
        # your logic resulting in having a variable your_data
        serializer = QuizSerializer(data=your_data)
        if serializer.is_valid():
            serializer.save()
            # return the data of your new instance here)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        
 
    

推荐阅读