【问题标题】:Django Having Error in Production on an ajax requestDjango 在 ajax 请求的生产中出现错误
【发布时间】:2021-10-19 06:05:54
【问题描述】:

我正在创建一个 django 项目,并尝试使用指南。我的代码在开发中工作,但是一旦我将代码推送到生产环境,我就会在 ajax 请求上出错。我看到错误发生在我获取键的视图级别,键是一个名为“文本”的字段。在开发中,使用它来提交测验效果很好,但在开发中却不行。我尝试使用 pk 进行提交,但它返回错误并且无法创建准确的结果实例。下面是我的模型的实例和视图。

错误

File "/home/django/.local/lib/python3.9/site-packages/django/db/models/query.py", line 435, in get
    raise self.model.DoesNotExist(
quiz.models.Question.DoesNotExist: Question matching query does not exist.
models.py 

from django.db import models
import random
from account.models import Profile
from django.urls import reverse
import datetime
from django.utils import timezone
from ckeditor_uploader.fields import RichTextUploadingField


class PublishedBookManager(models.Manager):
    def get_queryset(self):
        return super(PublishedBookManager, self).get_queryset().filter(publish_book=True)

class Book(models.Model):
    name = models.CharField(max_length=120)
    description = models.TextField()
    created_by = models.ForeignKey(Profile, default=1, null=True, on_delete=models.SET_NULL)
    number_of_questions = models.IntegerField()
    number_of_sections = models.IntegerField()
    time = models.IntegerField(help_text="duration of the quiz in minutes")
    required_score_to_pass = models.IntegerField(help_text="required score in %")
    start_date = models.DateTimeField(default=timezone.now)
    publish_book = models.BooleanField(default=False)
    date_created = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)

    objects = models.Manager() 
    published = PublishedBookManager()

    def __str__(self):
        return f"{self.name}"

    def get_absolute_url(self):
        return reverse('quiz:book-detail-view', args=[self.pk])


class PublishedQuizManager(models.Manager):
    def get_queryset(self):
        return super(PublishedQuizManager, self).get_queryset().filter(publish_quiz=True)


class Quiz(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE, blank=True, null=True)
    name = models.CharField(max_length=120)
    description = models.TextField()
    created_by = models.ForeignKey(Profile, default=1, null=True, on_delete=models.SET_NULL)
    number_of_questions = models.IntegerField()
    time = models.IntegerField(help_text="duration of the quiz in minutes")
    required_score_to_pass = models.IntegerField(help_text="required score in %")
    completed_users = models.ManyToManyField(Profile, blank=True, related_name='completed_users_quiz')
    publish_quiz = models.BooleanField(default=False)
    start_date = models.DateTimeField(default=timezone.now)
    deadline_date = models.DateTimeField(default=timezone.now)
    date_created = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)

    objects = models.Manager() 
    published = PublishedQuizManager()

    def __str__(self):
        return f"{self.book.name} = {self.name}"

    def get_questions(self):
        questions = list(self.question_set.all())
        random.shuffle(questions)
        return questions[:self.number_of_questions]


    class Meta:
        verbose_name_plural = 'Quizes'


    def get_absolute_url(self):
        return reverse('quiz:quiz-view',  kwargs={'book_pk': self.book.pk, "pk": self.pk})

class Question(models.Model):
    # text = models.TextField()
    text = RichTextUploadingField(unique=True)
    second_text = models.TextField()
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
    date_created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.text)

    def get_answers(self):
        return self.answer_set.all()

    def get_absolute_url(self):
        return reverse('quiz:quiz-view', kwargs={'question_pk': self.pk,})

class Answer(models.Model):
    text = models.CharField(max_length=255)
    correct = models.BooleanField(default=False)
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    date_created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"question: {self.question.text}, answer: {self.text}, correct: {self.correct}"

class Result(models.Model):
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
    user = models.ForeignKey(Profile, on_delete=models.CASCADE)
    score = models.FloatField()
    date_created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.pk)



views.py

def save_quiz_view(request, pk, book_pk, question_pk):
    # if request.user in 
    quiz = Quiz.objects.get(pk=pk)
    # Submition of result only occurs if a user is not in the completed users field. If they are already
    #  in the completed users ManyToMany field, then it won't save. But if not, it will save.
    if request.is_ajax() and not request.user.profile in quiz.completed_users.all():
        questions = []
        data = request.POST
        data_ = dict(data.lists())

        data_.pop('csrfmiddlewaretoken')

        # try:
        #     question = get_object_or_404(Question, pk=pk)
        #     questions.append(question)
        # except Question.DoesNotExist:
        #     pass

        for k in data_.keys():
            # print('key: ', k)
            # question = Question.objects.get(text=k)
            question = Question.objects.get(text=k)
            questions.append(question)
        # print(questions)

        user = request.user.profile
        quiz = Quiz.objects.get(pk=pk)

        if request.user.is_authenticated:
            if not user in quiz.completed_users.all():
                quiz.completed_users.add(user)

        score = 0
        multiplier = 100 / quiz.number_of_questions
        results = []
        correct_answer = None

        for q in questions:
            a_selected = request.POST.get(q.text)

            if a_selected != "":
                question_answers = Answer.objects.filter(question=q)
                for a in question_answers:
                    if a_selected == a.text:
                        if a.correct:
                            score += 1
                            correct_answer = a.text
                    else:
                        if a.correct:
                            correct_answer = a.text

                results.append({str(q): {'correct_answer': correct_answer, 'answered': a_selected}})
            else:
                results.append({str(q): 'not answered'})
            
        score_ = score #* multiplier
        Result.objects.create(quiz=quiz, user=user, score=score_)

        if score_:#>= quiz.required_score_to_pass:
            return JsonResponse({'passed': True, 'score': score_, 'results': results})
        else:
            return JsonResponse({'passed': False, 'score': score_, 'results': results})

【问题讨论】:

  • 您收到什么错误消息?
  • 嗨,我已经在生产中更新了带有错误消息的问题,谢谢。
  • 始终发布整个回溯。仅发布最后一个错误无济于事。话虽这么说,它看起来像question = Question.objects.get(text=k) 导致它,所以显然你的数据库中没有这样的Question

标签: javascript python django


【解决方案1】:

让我们看看Django manual 对此有何评论...

当未找到预期对象时,ORM 会引发此异常。例如,QuerySet.get() 将在给定查找找不到对象时引发它。

尝试运行:

for k in data_.keys():
  try:
    question = Question.objects.get(text=k)
  except Question.DoesNotExist:
    print(f'question with text "{k}" is not found')
  questions.append(question)

并通过手动运行 SQL 查询来检查您是否在 DB 中有此文本:

select * from question where text = 'not found k';

【讨论】:

  • 您好,我有兴趣在您的邮件中向您发送测验应用程序,希望您不要介意,谢谢。
  • @Arthur 不确定我是否有时间审查整个项目
【解决方案2】:

总是使用 try.. 除了当你想得到或者你可以做的时候阻止

q=Question.objects.filter(a=blah, b=blah)
If q is not None
    my_q = q.first()

如果什么都看不到,Get 总是会抛出错误...过滤器不会

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 2021-01-19
    • 2022-10-20
    • 2013-02-15
    • 1970-01-01
    相关资源
    最近更新 更多