Skip to content

Commit

Permalink
Merge pull request #151 from YDX-2147483647/perf
Browse files Browse the repository at this point in the history
perf: 组卷时改用`bulk_create`;fix: Inconsistent cache key
  • Loading branch information
YDX-2147483647 authored Aug 25, 2024
2 parents 57b5ab3 + a09ab66 commit 5edadcc
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 18 deletions.
2 changes: 1 addition & 1 deletion contest/quiz/templates/contest.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<article class="mx-auto max-w-2xl pb-6 prose">
<form action="{% url 'quiz:contest_submit' %}" method="post">
{% csrf_token %}
{% for a in draft_response.answer_set.all %}
{% for a in answer_set.all %}
<fieldset class="my-4 p-4 sm:px-6 lg:px-8 bg-white shadow disabled:text-gray-400"
{% if draft_response.outdated %}disabled{% endif %}>
<p class="text-lg my-0">
Expand Down
35 changes: 18 additions & 17 deletions contest/quiz/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@
from django.views.generic import TemplateView

from .constants import constants
from .models import Choice, DraftResponse, Question
from .models import Choice, DraftAnswer, DraftResponse, Question
from .util import is_open, is_student, is_student_taking_contest, pass_or_forbid, student_only

if TYPE_CHECKING:
from typing import Any, Literal

from django.contrib.auth.models import AnonymousUser

from .models import DraftAnswer, Student, User
from .models import Student, User
from .util import AuthenticatedHttpRequest


def continue_or_finalize(student_: Student) -> bool:
def continue_or_finalize(draft_response: DraftResponse) -> bool:
"""自动提交
若草稿已超期,则定稿,否则什么也不做。
Expand All @@ -47,13 +47,9 @@ def continue_or_finalize(student_: Student) -> bool:
https://docs.djangoproject.com/en/4.2/ref/models/instances/#django.db.models.Model.delete
https://docs.djangoproject.com/en/4.2/ref/models/instances/#refreshing-objects-from-database
"""
draft_response: DraftResponse = student_.draft_response

if draft_response.outdated():
# 提交之前的草稿
cache_key = f"{student_.user}_json"
# 从 Redis 获取现有的答案缓存
cached_answers = cache.get(cache_key, {})
cached_answers = cache.get(f"{draft_response.id}_json", {})

if cached_answers:
for question_id, choice_id in cached_answers.items():
Expand All @@ -77,16 +73,18 @@ def continue_or_finalize(student_: Student) -> bool:

answer.save()

cache.delete(f"{student_.user}_json")
cache.delete(f"{student_.user}_ddl")
cache.delete(f"{draft_response.id}_json")
cache.delete(f"{draft_response.id}_ddl")

# 提交之前的草稿

# 1. Convert from draft
response, answers = student_.draft_response.finalize(submit_at=timezone.now())
response, answers = draft_response.finalize(submit_at=timezone.now())

# 2. Save
response.save()
response.answer_set.bulk_create(answers)
student_.draft_response.delete()
draft_response.delete()

return True

Expand All @@ -103,7 +101,7 @@ def manage_status(
if not hasattr(student, "draft_response"):
return "not taking"
else:
finalized = continue_or_finalize(student)
finalized = continue_or_finalize(student.draft_response)
if finalized:
return "deadline passed"
else:
Expand Down Expand Up @@ -222,16 +220,19 @@ def contest(request: AuthenticatedHttpRequest) -> HttpResponse:

# 保存
draft_response.save()
for q in questions:
draft_response.answer_set.create(
question=q,
)
draft_response.answer_set.bulk_create(
[DraftAnswer(question=q, response=draft_response) for q in questions]
)

return render(
request,
"contest.html",
{
"draft_response": draft_response,
# 为渲染模板预先从数据库查询相关内容
"answer_set": draft_response.answer_set.select_related(
"question"
).prefetch_related("question__choice_set"),
"constants": constants,
},
)
Expand Down

0 comments on commit 5edadcc

Please sign in to comment.