Skip to content

Commit

Permalink
refactor: continue_or_finalize
Browse files Browse the repository at this point in the history
  • Loading branch information
YDX-2147483647 committed Aug 8, 2023
1 parent 643a177 commit 26088be
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 12 deletions.
37 changes: 37 additions & 0 deletions contest/quiz/tests.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from datetime import timedelta

from django.test import TestCase
from django.urls import reverse
from django.utils import timezone

from .constants import constants
from .models import (
Answer,
Choice,
Expand Down Expand Up @@ -64,6 +67,40 @@ def test_contest_view(self):
response = self.client.get(reverse("quiz:contest"))
self.assertEqual(response.status_code, 200)

def test_auto_submission(self):
"""自动提交"""
response = self.client.get(reverse("quiz:index"))
self.assertEqual(response.context["status"], "")

assert len(self.user.student.response_set.all()) == 0

self.client.force_login(self.user)
response = self.client.get(reverse("quiz:index"))
self.assertEqual(response.context["status"], "not taking")

# 前往答题
self.client.get(reverse("quiz:contest"))
response = self.client.get(reverse("quiz:index"))
self.assertEqual(response.context["status"], "taking contest")

# “时光飞逝”
self.user.student.draft_response.deadline -= constants.DEADLINE_DURATION
# -1 s
self.user.student.draft_response.deadline -= timedelta(seconds=1)
self.user.student.draft_response.save()

response = self.client.get(reverse("quiz:index"))
self.assertEqual(response.context["status"], "deadline passed")
self.assertEqual(len(self.user.student.response_set.all()), 1)
# `self.user.student.draft_response`访问在先,自动提交在后。
# 两边的 student 在数据库中相同,但并非 python 类的同一实例。
# 故必须刷新缓存的关系,不然`student.draft_response`总仍存在。
self.user.student.refresh_from_db()
self.assertFalse(hasattr(self.user.student, "draft_response"))

response = self.client.get(reverse("quiz:index"))
self.assertEqual(response.context["status"], "not taking")

def test_empty_response(self):
"""正常作答,但交白卷"""
self.client.force_login(self.user)
Expand Down
47 changes: 35 additions & 12 deletions contest/quiz/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,49 @@ def is_student_taking_contest(user: AbstractBaseUser | AnonymousUser) -> bool:
return hasattr(user, "student") and hasattr(user.student, "draft_response")


def continue_or_finalize(draft: DraftResponse) -> bool:
"""自动提交
若草稿已超期,则定稿,否则什么也不做。
:return: 是否如此操作(定稿)了
定稿只会修改数据库,而 python 实例仍存在。
可用其它 model 的`refresh_from_db`刷新缓存的关系。
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
"""

if draft.outdated():
# 提交之前的草稿
response, answers = draft.finalize(
submit_at=draft.deadline + constants.DEADLINE_DURATION
)

response.save()
response.answer_set.bulk_create(answers)

draft.delete()

return True

return False


@require_GET
def index(request: HttpRequest) -> HttpResponse:
if request.user.is_authenticated and is_student(request.user):
student = request.user.student

if not hasattr(student, "draft_response"):
status = "not taking"
elif not student.draft_response.outdated():
status = "taking contest"
else:
status = "deadline passed"

# 提交之前的草稿
response, answers = student.draft_response.finalize(
submit_at=student.draft_response.deadline + constants.DEADLINE_DURATION
)

response.save()
response.answer_set.bulk_create(answers)
student.draft_response.delete()
finalized = continue_or_finalize(student.draft_response)
if finalized:
status = "deadline passed"
else:
status = "taking contest"
else:
status = ""

Expand Down

0 comments on commit 26088be

Please sign in to comment.