diff --git a/judge/migrations/0193_remove_old_course_problems.py b/judge/migrations/0193_remove_old_course_problems.py
new file mode 100644
index 0000000..809b3e9
--- /dev/null
+++ b/judge/migrations/0193_remove_old_course_problems.py
@@ -0,0 +1,29 @@
+# Generated by Django 3.2.18 on 2024-09-03 14:33
+
+from django.db import migrations, models
+
+
+def migrate_problems_to_courselessonproblem(apps, schema_editor):
+ CourseLesson = apps.get_model("judge", "CourseLesson")
+ CourseLessonProblem = apps.get_model("judge", "CourseLessonProblem")
+
+ for lesson in CourseLesson.objects.all():
+ for problem in lesson.problems.all():
+ CourseLessonProblem.objects.create(
+ lesson=lesson, problem=problem, order=1, score=1
+ )
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("judge", "0192_course_lesson_problem"),
+ ]
+
+ operations = [
+ migrations.RunPython(migrate_problems_to_courselessonproblem),
+ migrations.RemoveField(
+ model_name="courselesson",
+ name="problems",
+ ),
+ ]
diff --git a/judge/models/course.py b/judge/models/course.py
index 9b02d63..003c695 100644
--- a/judge/models/course.py
+++ b/judge/models/course.py
@@ -162,10 +162,18 @@ class CourseLesson(models.Model):
)
title = models.TextField(verbose_name=_("course title"))
content = models.TextField(verbose_name=_("course content"))
- problems = models.ManyToManyField(Problem, verbose_name=_("problem"), blank=True)
order = models.IntegerField(verbose_name=_("order"), default=0)
points = models.IntegerField(verbose_name=_("points"))
+ def get_absolute_url(self):
+ return reverse(
+ "course_lesson_detail",
+ args=(
+ self.course.slug,
+ self.id,
+ ),
+ )
+
class CourseLessonProblem(models.Model):
lesson = models.ForeignKey(
diff --git a/judge/views/course.py b/judge/views/course.py
index ce74d4a..cb0083c 100644
--- a/judge/views/course.py
+++ b/judge/views/course.py
@@ -130,7 +130,7 @@ class CourseDetail(CourseDetailMixin, DetailView):
def get_context_data(self, **kwargs):
context = super(CourseDetail, self).get_context_data(**kwargs)
- lessons = self.course.lessons.prefetch_related("problems").all()
+ lessons = self.course.lessons.prefetch_related("lesson_problems").all()
context["title"] = self.course.name
context["page_type"] = "home"
context["lessons"] = lessons
@@ -190,7 +190,7 @@ class CourseLessonDetail(CourseDetailMixin, DetailView):
class CourseLessonForm(forms.ModelForm):
class Meta:
model = CourseLesson
- fields = ["order", "title", "points", "content", "problems"]
+ fields = ["order", "title", "points", "content"]
widgets = {
"title": forms.TextInput(),
"content": HeavyPreviewPageDownWidget(preview=reverse_lazy("blog_preview")),
@@ -312,13 +312,13 @@ class CourseStudentResults(CourseEditableMixin, DetailView):
def get_grades(self):
students = self.course.get_students()
students.sort(key=lambda u: u.username.lower())
- lessons = self.course.lessons.prefetch_related("problems").all()
+ lessons = self.course.lessons.prefetch_related("lesson_problems").all()
grades = {s: calculate_lessons_progress(s, lessons) for s in students}
return grades
def get_context_data(self, **kwargs):
context = super(CourseStudentResults, self).get_context_data(**kwargs)
- context["title"] = _("Grades in %(course_name)s") % {
+ context["title"] = _("Grades in %(course_name)s") % {
"course_name": self.course.name,
}
context["content_title"] = mark_safe(
@@ -374,16 +374,19 @@ class CourseStudentResultsLesson(CourseEditableMixin, DetailView):
def get_context_data(self, **kwargs):
context = super(CourseStudentResultsLesson, self).get_context_data(**kwargs)
context["lesson"] = self.lesson
- context["title"] = _("Grades of %(lesson_name)s in %(course_name)s") % {
+ context["title"] = _("Grades of %(lesson_name)s in %(course_name)s") % {
"course_name": self.course.name,
"lesson_name": self.lesson.title,
}
context["content_title"] = mark_safe(
- _("Grades of %(lesson_name)s in %(course_name)s")
+ _(
+ "Grades of %(lesson_name)s in %(course_name)s"
+ )
% {
"course_name": self.course.name,
"lesson_name": self.lesson.title,
- "url": self.course.get_absolute_url(),
+ "url_course": self.course.get_absolute_url(),
+ "url_lesson": self.lesson.get_absolute_url(),
}
)
context["page_type"] = "grades"
diff --git a/locale/vi/LC_MESSAGES/django.po b/locale/vi/LC_MESSAGES/django.po
index d4d3a88..0aa81e3 100644
--- a/locale/vi/LC_MESSAGES/django.po
+++ b/locale/vi/LC_MESSAGES/django.po
@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lqdoj2\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-08-14 16:14+0700\n"
+"POT-Creation-Date: 2024-09-03 21:28+0700\n"
"PO-Revision-Date: 2021-07-20 03:44\n"
"Last-Translator: Icyene\n"
"Language-Team: Vietnamese\n"
@@ -18,23 +18,23 @@ msgstr ""
"X-Crowdin-Project-ID: 466004\n"
"X-Crowdin-File-ID: 5\n"
-#: chat_box/models.py:22 chat_box/models.py:83
+#: chat_box/models.py:22 chat_box/models.py:84
msgid "last seen"
msgstr "xem lần cuối"
-#: chat_box/models.py:54 chat_box/models.py:79 chat_box/models.py:95
-#: judge/admin/interface.py:151 judge/models/contest.py:701
-#: judge/models/contest.py:907 judge/models/course.py:129
-#: judge/models/profile.py:475 judge/models/profile.py:549
+#: chat_box/models.py:55 chat_box/models.py:80 chat_box/models.py:96
+#: judge/admin/interface.py:151 judge/models/contest.py:703
+#: judge/models/contest.py:909 judge/models/course.py:129
+#: judge/models/profile.py:465 judge/models/profile.py:539
msgid "user"
msgstr "người dùng"
-#: chat_box/models.py:56 judge/models/comment.py:45
+#: chat_box/models.py:57 judge/models/comment.py:45
#: judge/models/notification.py:31
msgid "posted time"
msgstr "thời gian đăng"
-#: chat_box/models.py:58 judge/models/comment.py:50
+#: chat_box/models.py:59 judge/models/comment.py:50
msgid "body of comment"
msgstr "nội dung bình luận"
@@ -57,7 +57,7 @@ msgstr "Gần đây"
#: templates/internal/problem/problem.html:63
#: templates/organization/org-left-sidebar.html:12
#: templates/organization/users-table.html:19
-#: templates/problem/left-sidebar.html:6
+#: templates/problem/left-sidebar.html:13
#: templates/problem/problem-list-tabs.html:6
#: templates/submission/info-base.html:12 templates/submission/list.html:394
#: templates/submission/submission-list-tabs.html:15
@@ -199,7 +199,7 @@ msgstr[0] "%d thí sinh đã được tính điểm lại."
msgid "Recalculate results"
msgstr "Tính toán lại kết quả"
-#: judge/admin/contest.py:534 judge/admin/organization.py:100
+#: judge/admin/contest.py:534 judge/admin/organization.py:98
msgid "username"
msgstr "tên đăng nhập"
@@ -231,7 +231,7 @@ msgstr ""
msgid "diff"
msgstr ""
-#: judge/admin/organization.py:62 judge/admin/problem.py:290
+#: judge/admin/organization.py:60 judge/admin/problem.py:290
#: judge/admin/profile.py:122
msgid "View on site"
msgstr "Xem trên trang"
@@ -536,7 +536,7 @@ msgstr "Mật khẩu không được toàn chữ số."
msgid "Bug Report"
msgstr "Báo cáo lỗi"
-#: judge/custom_translations.py:21 judge/views/course.py:76
+#: judge/custom_translations.py:21 judge/views/course.py:96
#: templates/course/list.html:8
msgid "Courses"
msgstr "Khóa học"
@@ -784,7 +784,7 @@ msgstr "mô tả"
msgid "problems"
msgstr "bài tập"
-#: judge/models/contest.py:137 judge/models/contest.py:706
+#: judge/models/contest.py:137 judge/models/contest.py:708
msgid "start time"
msgstr "thời gian bắt đầu"
@@ -930,7 +930,7 @@ msgstr "riêng tư với các tổ chức"
#: judge/models/contest.py:246 judge/models/course.py:33
#: judge/models/interface.py:93 judge/models/problem.py:281
-#: judge/models/profile.py:177
+#: judge/models/profile.py:167
msgid "organizations"
msgstr "tổ chức"
@@ -942,7 +942,7 @@ msgstr "Nếu riêng tư, chỉ những tổ chức này thấy được kỳ th
msgid "OpenGraph image"
msgstr "Hình ảnh OpenGraph"
-#: judge/models/contest.py:253 judge/models/profile.py:115
+#: judge/models/contest.py:253
msgid "Logo override image"
msgstr "Hình ảnh ghi đè logo"
@@ -1020,305 +1020,306 @@ msgid ""
"limit."
msgstr "Số bài nộp tối đa mỗi phút. Để trống nếu không muốn giới hạn."
-#: judge/models/contest.py:359
+#: judge/models/contest.py:358
msgid "End time must be after start time"
msgstr "Thời gian kết thúc phải sau thời gian bắt đầu"
-#: judge/models/contest.py:660
+#: judge/models/contest.py:662
msgid "See private contests"
msgstr ""
-#: judge/models/contest.py:661
+#: judge/models/contest.py:663
msgid "Edit own contests"
msgstr ""
-#: judge/models/contest.py:662
+#: judge/models/contest.py:664
msgid "Edit all contests"
msgstr ""
-#: judge/models/contest.py:663
+#: judge/models/contest.py:665
msgid "Clone contest"
msgstr ""
-#: judge/models/contest.py:664 templates/contest/moss.html:72
+#: judge/models/contest.py:666 templates/contest/moss.html:72
msgid "MOSS contest"
msgstr ""
-#: judge/models/contest.py:665
+#: judge/models/contest.py:667
msgid "Rate contests"
msgstr ""
-#: judge/models/contest.py:666
+#: judge/models/contest.py:668
msgid "Contest access codes"
msgstr ""
-#: judge/models/contest.py:667
+#: judge/models/contest.py:669
msgid "Create private contests"
msgstr ""
-#: judge/models/contest.py:668
+#: judge/models/contest.py:670
msgid "Change contest visibility"
msgstr ""
-#: judge/models/contest.py:669
+#: judge/models/contest.py:671
msgid "Edit contest problem label script"
msgstr "Cách hiển thị thứ tự bài tập"
-#: judge/models/contest.py:671 judge/models/contest.py:832
-#: judge/models/contest.py:910 judge/models/contest.py:940
-#: judge/models/contest.py:1019 judge/models/submission.py:116
+#: judge/models/contest.py:673 judge/models/contest.py:834
+#: judge/models/contest.py:912 judge/models/contest.py:942
+#: judge/models/contest.py:1021 judge/models/submission.py:116
msgid "contest"
msgstr "kỳ thi"
-#: judge/models/contest.py:672
+#: judge/models/contest.py:674
msgid "contests"
msgstr "kỳ thi"
-#: judge/models/contest.py:695
+#: judge/models/contest.py:697
msgid "associated contest"
msgstr ""
-#: judge/models/contest.py:708
+#: judge/models/contest.py:710 judge/models/course.py:176
msgid "score"
msgstr "điểm"
-#: judge/models/contest.py:709
+#: judge/models/contest.py:711
msgid "cumulative time"
msgstr "tổng thời gian"
-#: judge/models/contest.py:711
+#: judge/models/contest.py:713
msgid "is disqualified"
msgstr "đã bị loại"
-#: judge/models/contest.py:713
+#: judge/models/contest.py:715
msgid "Whether this participation is disqualified."
msgstr "Quyết định thí sinh có bị loại không."
-#: judge/models/contest.py:715
+#: judge/models/contest.py:717
msgid "tie-breaking field"
msgstr ""
-#: judge/models/contest.py:717
+#: judge/models/contest.py:719
msgid "virtual participation id"
msgstr "id lần tham gia ảo"
-#: judge/models/contest.py:719
+#: judge/models/contest.py:721
msgid "0 means non-virtual, otherwise the n-th virtual participation."
msgstr "0 nghĩa là tham gia chính thức, ngược lại là lần tham gia ảo thứ n."
-#: judge/models/contest.py:722
+#: judge/models/contest.py:724
msgid "contest format specific data"
msgstr ""
-#: judge/models/contest.py:725
+#: judge/models/contest.py:727
msgid "same as format_data, but including frozen results"
msgstr ""
-#: judge/models/contest.py:729
+#: judge/models/contest.py:731
msgid "final score"
msgstr "điểm"
-#: judge/models/contest.py:731
+#: judge/models/contest.py:733
msgid "final cumulative time"
msgstr "tổng thời gian"
-#: judge/models/contest.py:807
+#: judge/models/contest.py:809
#, python-format
msgid "%s spectating in %s"
msgstr "%s đang theo dõi trong %s"
-#: judge/models/contest.py:812
+#: judge/models/contest.py:814
#, python-format
msgid "%s in %s, v%d"
msgstr "%s trong %s, v%d"
-#: judge/models/contest.py:817
+#: judge/models/contest.py:819
#, python-format
msgid "%s in %s"
msgstr "%s trong %s"
-#: judge/models/contest.py:820
+#: judge/models/contest.py:822
msgid "contest participation"
msgstr "lần tham gia kỳ thi"
-#: judge/models/contest.py:821
+#: judge/models/contest.py:823
msgid "contest participations"
msgstr "lần tham gia kỳ thi"
-#: judge/models/contest.py:828 judge/models/contest.py:881
-#: judge/models/contest.py:943 judge/models/course.py:165
+#: judge/models/contest.py:830 judge/models/contest.py:883
+#: judge/models/contest.py:945 judge/models/course.py:165
#: judge/models/problem.py:609 judge/models/problem.py:616
#: judge/models/problem.py:637 judge/models/problem.py:668
#: judge/models/problem_data.py:50
msgid "problem"
msgstr "bài tập"
-#: judge/models/contest.py:836 judge/models/contest.py:893
+#: judge/models/contest.py:838 judge/models/contest.py:895
#: judge/models/course.py:167 judge/models/problem.py:209
msgid "points"
msgstr "điểm"
-#: judge/models/contest.py:837
+#: judge/models/contest.py:839
msgid "partial"
msgstr "thành phần"
-#: judge/models/contest.py:838 judge/models/contest.py:895
+#: judge/models/contest.py:840 judge/models/contest.py:897
msgid "is pretested"
msgstr "dùng pretest"
-#: judge/models/contest.py:839 judge/models/course.py:166
-#: judge/models/interface.py:48
+#: judge/models/contest.py:841 judge/models/course.py:166
+#: judge/models/course.py:175 judge/models/interface.py:48
msgid "order"
msgstr "thứ tự"
-#: judge/models/contest.py:841
+#: judge/models/contest.py:843
msgid "visible testcases"
msgstr "hiển thị test"
-#: judge/models/contest.py:846
+#: judge/models/contest.py:848
msgid "Maximum number of submissions for this problem, or 0 for no limit."
msgstr "Số lần nộp tối đa, đặt là 0 nếu không có giới hạn."
-#: judge/models/contest.py:848
+#: judge/models/contest.py:850
msgid "max submissions"
msgstr "số lần nộp tối đa"
-#: judge/models/contest.py:851
+#: judge/models/contest.py:853
msgid "Why include a problem you can't submit to?"
msgstr ""
-#: judge/models/contest.py:855
+#: judge/models/contest.py:857
#, fuzzy
#| msgid "Only for format new IOI. Separated by commas, e.g: 2, 3"
msgid "Separated by commas, e.g: 2, 3"
msgstr ""
"Chỉ dùng với format IOI mới. Các sub cách nhau bởi dấu phẩy. Ví dụ: 2, 3"
-#: judge/models/contest.py:856
+#: judge/models/contest.py:858
msgid "hidden subtasks"
msgstr "Đóng băng subtasks"
-#: judge/models/contest.py:868
+#: judge/models/contest.py:870
msgid "contest problem"
msgstr "bài trong kỳ thi"
-#: judge/models/contest.py:869
+#: judge/models/contest.py:871
msgid "contest problems"
msgstr "bài trong kỳ thi"
-#: judge/models/contest.py:875 judge/models/submission.py:274
+#: judge/models/contest.py:877 judge/models/submission.py:274
msgid "submission"
msgstr "bài nộp"
-#: judge/models/contest.py:888 judge/models/contest.py:914
+#: judge/models/contest.py:890 judge/models/contest.py:916
msgid "participation"
msgstr "lần tham gia"
-#: judge/models/contest.py:896
+#: judge/models/contest.py:898
msgid "Whether this submission was ran only on pretests."
msgstr "Quyết định bài nộp chỉ được chạy trên pretest không."
-#: judge/models/contest.py:901
+#: judge/models/contest.py:903
msgid "contest submission"
msgstr "bài nộp kỳ thi"
-#: judge/models/contest.py:902
+#: judge/models/contest.py:904
msgid "contest submissions"
msgstr "bài nộp kỳ thi"
-#: judge/models/contest.py:918
+#: judge/models/contest.py:920
msgid "rank"
msgstr "rank"
-#: judge/models/contest.py:919
+#: judge/models/contest.py:921
msgid "rating"
msgstr "rating"
-#: judge/models/contest.py:920
+#: judge/models/contest.py:922
msgid "raw rating"
msgstr "rating thật"
-#: judge/models/contest.py:921
+#: judge/models/contest.py:923
msgid "contest performance"
msgstr ""
-#: judge/models/contest.py:922
+#: judge/models/contest.py:924
msgid "last rated"
msgstr "lần cuối được xếp hạng"
-#: judge/models/contest.py:926
+#: judge/models/contest.py:928
msgid "contest rating"
msgstr "rating kỳ thi"
-#: judge/models/contest.py:927
+#: judge/models/contest.py:929
msgid "contest ratings"
msgstr "rating kỳ thi"
-#: judge/models/contest.py:951
+#: judge/models/contest.py:953
msgid "contest moss result"
msgstr "kết quả MOSS kỳ thi"
-#: judge/models/contest.py:952
+#: judge/models/contest.py:954
msgid "contest moss results"
msgstr "kết quả MOSS kỳ thi"
-#: judge/models/contest.py:957
+#: judge/models/contest.py:959
msgid "clarified problem"
msgstr ""
-#: judge/models/contest.py:959
+#: judge/models/contest.py:961
msgid "clarification body"
msgstr ""
-#: judge/models/contest.py:961
+#: judge/models/contest.py:963
msgid "clarification timestamp"
msgstr ""
-#: judge/models/contest.py:980
+#: judge/models/contest.py:982
msgid "contests summary"
msgstr "tổng kết kỳ thi"
-#: judge/models/contest.py:981
+#: judge/models/contest.py:983
msgid "contests summaries"
msgstr "tổng kết kỳ thi"
-#: judge/models/contest.py:992 judge/models/contest.py:999
+#: judge/models/contest.py:994 judge/models/contest.py:1001
msgid "official contest category"
msgstr "loại kỳ thi chính thức"
-#: judge/models/contest.py:1000
+#: judge/models/contest.py:1002
msgid "official contest categories"
msgstr "các loại kỳ thi chính thức"
-#: judge/models/contest.py:1005 judge/models/contest.py:1012
+#: judge/models/contest.py:1007 judge/models/contest.py:1014
msgid "official contest location"
msgstr "địa điểm kỳ thi chính thức"
-#: judge/models/contest.py:1013
+#: judge/models/contest.py:1015
msgid "official contest locations"
msgstr "các địa điểm kỳ thi chính thức"
-#: judge/models/contest.py:1025
+#: judge/models/contest.py:1027
msgid "contest category"
msgstr "loại kỳ thi"
-#: judge/models/contest.py:1028
+#: judge/models/contest.py:1030
msgid "year"
msgstr "năm"
-#: judge/models/contest.py:1031
+#: judge/models/contest.py:1033
msgid "contest location"
msgstr "địa điểm kỳ thi"
-#: judge/models/contest.py:1036
+#: judge/models/contest.py:1038
msgid "official contest"
msgstr "kỳ thi chính thức"
-#: judge/models/contest.py:1037
+#: judge/models/contest.py:1039
msgid "official contests"
msgstr "các kỳ thi chính thức"
#: judge/models/course.py:12 templates/course/grades.html:88
+#: templates/course/grades_lesson.html:88
msgid "Student"
msgstr "Học sinh"
@@ -2106,150 +2107,144 @@ msgstr "Số người tối đa trong tổ chức, chỉ áp dụng với tổ c
msgid "Student access code"
msgstr "Mã truy cập cho học sinh"
-#: judge/models/profile.py:120
-msgid ""
-"This image will replace the default site logo for users viewing the "
-"organization."
-msgstr "Ảnh này sẽ thay thế logo mặc định khi ở trong tổ chức."
-
-#: judge/models/profile.py:176 judge/models/profile.py:208
-#: judge/models/profile.py:481 judge/models/profile.py:556
+#: judge/models/profile.py:166 judge/models/profile.py:198
+#: judge/models/profile.py:471 judge/models/profile.py:546
msgid "organization"
msgstr ""
-#: judge/models/profile.py:183
+#: judge/models/profile.py:173
msgid "user associated"
msgstr ""
-#: judge/models/profile.py:186
+#: judge/models/profile.py:176
msgid "self-description"
msgstr ""
-#: judge/models/profile.py:190
+#: judge/models/profile.py:180
msgid "location"
msgstr ""
-#: judge/models/profile.py:196
+#: judge/models/profile.py:186
msgid "preferred language"
msgstr ""
-#: judge/models/profile.py:204
+#: judge/models/profile.py:194
msgid "last access time"
msgstr ""
-#: judge/models/profile.py:205
+#: judge/models/profile.py:195
msgid "last IP"
msgstr ""
-#: judge/models/profile.py:216
+#: judge/models/profile.py:206
msgid "display rank"
msgstr ""
-#: judge/models/profile.py:225
+#: judge/models/profile.py:215
msgid "comment mute"
msgstr ""
-#: judge/models/profile.py:226
+#: judge/models/profile.py:216
msgid "Some users are at their best when silent."
msgstr ""
-#: judge/models/profile.py:230
+#: judge/models/profile.py:220
msgid "unlisted user"
msgstr ""
-#: judge/models/profile.py:231
+#: judge/models/profile.py:221
msgid "User will not be ranked."
msgstr ""
-#: judge/models/profile.py:237
+#: judge/models/profile.py:227
msgid "current contest"
msgstr "kỳ thi hiện tại"
-#: judge/models/profile.py:244
+#: judge/models/profile.py:234
msgid "2FA enabled"
msgstr ""
-#: judge/models/profile.py:246
+#: judge/models/profile.py:236
msgid "check to enable TOTP-based two factor authentication"
msgstr "đánh dấu để sử dụng TOTP-based two factor authentication"
-#: judge/models/profile.py:252
+#: judge/models/profile.py:242
msgid "TOTP key"
msgstr "mã TOTP"
-#: judge/models/profile.py:253
+#: judge/models/profile.py:243
msgid "32 character base32-encoded key for TOTP"
msgstr ""
-#: judge/models/profile.py:255
+#: judge/models/profile.py:245
msgid "TOTP key must be empty or base32"
msgstr ""
-#: judge/models/profile.py:259
+#: judge/models/profile.py:249
msgid "internal notes"
msgstr "ghi chú nội bộ"
-#: judge/models/profile.py:262
+#: judge/models/profile.py:252
msgid "Notes for administrators regarding this user."
msgstr "Ghi chú riêng cho quản trị viên."
-#: judge/models/profile.py:267
+#: judge/models/profile.py:257
msgid "Custom background"
msgstr "Background tự chọn"
-#: judge/models/profile.py:270
+#: judge/models/profile.py:260
msgid "CSS custom background properties: url(\"image_url\"), color, etc"
msgstr "CSS background tự chọn. Ví dụ: url(\"image_url\"), white, ..."
-#: judge/models/profile.py:438
+#: judge/models/profile.py:428
msgid "user profile"
msgstr "thông tin người dùng"
-#: judge/models/profile.py:439
+#: judge/models/profile.py:429
msgid "user profiles"
msgstr "thông tin người dùng"
-#: judge/models/profile.py:445
+#: judge/models/profile.py:435
#, fuzzy
#| msgid "associated page"
msgid "profile associated"
msgstr "trang tương ứng"
-#: judge/models/profile.py:452
+#: judge/models/profile.py:442
msgid "t-shirt size"
msgstr ""
-#: judge/models/profile.py:457
+#: judge/models/profile.py:447
#, fuzzy
#| msgid "date of publishing"
msgid "date of birth"
msgstr "Ngày công bố"
-#: judge/models/profile.py:463
+#: judge/models/profile.py:453
msgid "address"
msgstr ""
-#: judge/models/profile.py:485
+#: judge/models/profile.py:475
msgid "request time"
msgstr "thời gian đăng ký"
-#: judge/models/profile.py:488
+#: judge/models/profile.py:478
msgid "state"
msgstr "trạng thái"
-#: judge/models/profile.py:495
+#: judge/models/profile.py:485
msgid "reason"
msgstr "lý do"
-#: judge/models/profile.py:498
+#: judge/models/profile.py:488
msgid "organization join request"
msgstr "đơn đăng ký tham gia"
-#: judge/models/profile.py:499
+#: judge/models/profile.py:489
msgid "organization join requests"
msgstr "đơn đăng ký tham gia"
-#: judge/models/profile.py:561
+#: judge/models/profile.py:551
#, fuzzy
#| msgid "last seen"
msgid "last visit"
@@ -3038,21 +3033,37 @@ msgstr "Mô tả vấn đề"
msgid "New clarification for %s"
msgstr "Thông báo mới cho %s"
-#: judge/views/course.py:199
+#: judge/views/course.py:265
#, python-format
msgid "Edit lessons for %(course_name)s"
msgstr "Chỉnh sửa bài học cho %(course_name)s"
-#: judge/views/course.py:203
+#: judge/views/course.py:269
#, python-format
msgid "Edit lessons for %(course_name)s"
msgstr "Chỉnh sửa bài học cho %(course_name)s"
-#: judge/views/course.py:242
+#: judge/views/course.py:321
+#, fuzzy, python-format
+#| msgid "Edit lessons for %(course_name)s"
+msgid "Grades in %(course_name)s"
+msgstr "Chỉnh sửa bài học cho %(course_name)s"
+
+#: judge/views/course.py:325
#, python-format
msgid "Grades in %(course_name)s"
msgstr "Điểm trong %(course_name)s"
+#: judge/views/course.py:377
+#, fuzzy, python-format
+msgid "Grades of %(lesson_name)s in %(course_name)s"
+msgstr "Chỉnh sửa bài học cho %(course_name)s"
+
+#: judge/views/course.py:382
+#, fuzzy, python-format
+msgid "Grades of %(lesson_name)s in %(course_name)s"
+msgstr "Điểm trong %(course_name)s"
+
#: judge/views/custom_file_upload.py:42
msgid "File Upload"
msgstr "Tải file lên"
@@ -3512,6 +3523,7 @@ msgid "Best solutions for {0}"
msgstr "Các bài nộp tốt nhất cho {0}"
#: judge/views/register.py:30 templates/course/grades.html:81
+#: templates/course/grades_lesson.html:81
#: templates/registration/registration_form.html:34
#: templates/user/base-users-table.html:5
#: templates/user/import/table_csv.html:4
@@ -4626,21 +4638,21 @@ msgstr "Kỳ thi sắp diễn ra"
msgid "Lessons"
msgstr "Bài học"
-#: templates/course/course.html:34
+#: templates/course/course.html:37
msgid "Total achieved points"
msgstr "Tổng điểm"
-#: templates/course/edit_lesson.html:28
+#: templates/course/edit_lesson.html:50
msgid "Add new"
msgstr "Thêm mới"
-#: templates/course/edit_lesson.html:36
+#: templates/course/edit_lesson.html:58
#: templates/organization/contest/edit.html:41
#: templates/organization/form.html:6
msgid "Please fix below errors"
msgstr "Vui lòng sửa các lỗi bên dưới"
-#: templates/course/edit_lesson.html:56
+#: templates/course/edit_lesson.html:107
#: templates/markdown_editor/markdown_editor.html:122
#: templates/organization/blog/edit.html:36
#: templates/organization/contest/edit.html:87
@@ -4648,19 +4660,22 @@ msgstr "Vui lòng sửa các lỗi bên dưới"
msgid "Save"
msgstr "Lưu"
-#: templates/course/grades.html:79
+#: templates/course/grades.html:79 templates/course/grades_lesson.html:79
msgid "Sort by"
msgstr "Sắp xếp theo"
-#: templates/course/grades.html:82 templates/user/user-problems.html:99
+#: templates/course/grades.html:82 templates/course/grades_lesson.html:82
+#: templates/user/user-problems.html:99
msgid "Score"
msgstr "Điểm"
-#: templates/course/grades.html:84 templates/internal/problem/problem.html:34
+#: templates/course/grades.html:84 templates/course/grades_lesson.html:84
+#: templates/internal/problem/problem.html:34
msgid "Search"
msgstr "Tìm kiếm"
-#: templates/course/grades.html:99 templates/submission/user-ajax.html:33
+#: templates/course/grades.html:99 templates/course/grades_lesson.html:99
+#: templates/submission/user-ajax.html:33
msgid "Total"
msgstr "Tổng điểm"
@@ -5105,11 +5120,11 @@ msgstr "Dạng bài"
msgid "Any additional note here"
msgstr "Lưu ý thêm cho admin"
-#: templates/problem/left-sidebar.html:3
+#: templates/problem/left-sidebar.html:10
msgid "Feed"
msgstr "Gợi ý"
-#: templates/problem/left-sidebar.html:4
+#: templates/problem/left-sidebar.html:11
#: templates/problem/problem-list-tabs.html:5
msgid "List"
msgstr "Danh sách"
@@ -6335,6 +6350,11 @@ msgstr "Thông tin"
msgid "Check all"
msgstr "Chọn tất cả"
+#~ msgid ""
+#~ "This image will replace the default site logo for users viewing the "
+#~ "organization."
+#~ msgstr "Ảnh này sẽ thay thế logo mặc định khi ở trong tổ chức."
+
#~ msgid "A ticket is added or updated"
#~ msgstr "Báo cáo"
diff --git a/templates/course/edit_lesson.html b/templates/course/edit_lesson.html
index 7426b8d..c160be4 100644
--- a/templates/course/edit_lesson.html
+++ b/templates/course/edit_lesson.html
@@ -16,11 +16,18 @@
{{ form.media.js }}
{% endblock %}