【问题标题】:Django Postgresql Error in Production (quiz.models.Question.DoesNotExist:)生产中的 Django Postgresql 错误 (quiz.models.Question.DoesNotExist:)
【发布时间】:2021-10-26 04:39:54
【问题描述】:

我正在使用指南创建一个测验应用程序。我的应用程序在使用 sqlite3 和 postgresql 数据库的开发中运行良好。但是当投入生产时,我在使用 postgresql 数据库时遇到了错误。所以我尝试在生产中使用我的开发 sqlite3 数据库来测试。我的 sqlite3 数据库在生产中运行良好,但 postgresql 在生产中无法运行。最初,我认为错误是在视图级别,但现在我看到来自 postgresql 的错误。可能是我的视图或模型架构中的错误。我真的说不出来。下面是我在生产中使用带有 gunicorn 和 nginx 的 linux 服务器的 postgresql 数据库时遇到的相应错误,整个模型设计和视图也在下面。谢谢,感谢您抽出宝贵时间为我的问题提供合适的答案。

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):
    # 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')

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

        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})

错误

django@UniqueAsf2:~/src$ python3 manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
October 26, 2021 - 03:57:12
Django version 3.2.8, using settings 'asf.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
[26/Oct/2021 03:57:18] "GET /quiz/1/1/ HTTP/1.1" 200 8065
Not Found: /quiz/1/1/assets/vendors/boxicons/css/boxicons.min.css
[26/Oct/2021 03:57:18] "GET /quiz/1/1/assets/vendors/boxicons/css/boxicons.min.css HTTP/1.1" 404 5612
[26/Oct/2021 03:57:18] "GET /quiz/1/1/data/ HTTP/1.1" 200 101
Internal Server Error: /quiz/1/1/save/
Traceback (most recent call last):
  File "/home/django/.local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/django/.local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/django/src/quiz/views.py", line 108, in save_quiz_view
    question = Question.objects.get(text=_k)
  File "/home/django/.local/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  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.

【问题讨论】:

  • 记录不存在。您的数据库并没有真正损坏。为什么不通过管理员手动创建记录并重新加载网页(会给您确认这是问题所在)。
  • 我使用管理面板手动创建了记录。

标签: python django postgresql


【解决方案1】:

Question 中的数据不是以简单文本形式存储的,因为您使用的是 RichTextUploadingField,它将文本转换为 HTML 格式以处理文本格式。因此,您不能直接比较两个字符串或对其进行搜索。

尝试使用icontains 在您的字段中检查字符串。这可能不适用于所有情况,因此您必须相应地进行处理。

questions = Question.objects.filter(text__icontains=k)
for question in questions:
    # Handle questions here

【讨论】:

  • 感谢您,我会立即尝试并就我的结果提供反馈。虽然,最初我只使用 Django TextField 提交的“文本”,但在使用 RichTextEditor 进行更改之前,它仍然返回生产中的错误。
  • 直接比较两个字符串总是有风险的,因为微小的差异可能会使您的查询失败。尝试对此进行某种搜索。 docs.djangoproject.com/en/3.2/topics/db/search
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 2012-08-10
  • 2020-01-30
  • 2016-04-03
  • 2015-05-15
  • 2012-04-08
相关资源
最近更新 更多