積分管理
為了鼓勵學生繳交作業,在這個專案裡設計了一個積分的機制,讓學生以繳交作業來累積點數,在課程的修課名單中也會增加一個欄位顯示每位學生目前所獲取的點數,以期透過同儕間的競爭心理,激勵學生繳交作業。
學生每次繳交作業可以取得 2 個積點,當教師完成評分時,受評的學生的作業成績如果超過 90 分可以獲得額外的 2 個積點,超過 80 分可以獲得額外 1 個積點。
定義積分紀錄資料模型
直接將積分紀錄的資料模型定義在現存的應用程式內即可,這邊選擇將其定義在應用程式 user
之下。請開啟 user/models.py
,修改第 3 行並新增第 35 - 47 行:
from course.models import Course, Assignment
- 第 3 行,新增引用作業資料模型
Assignment
class PointHistory(Model):
user = ForeignKey(User, CASCADE, related_name='point_list')
assignment = ForeignKey(Assignment, CASCADE, related_name='+')
reason = CharField('積點原因', max_length=100)
point = IntegerField('點數', default=0)
created = DateTimeField('積點時間', auto_now_add=True)
def __str__(self):
return "{}: {} {}點".format(
self.created,
self.reason,
self.point
)
定義路徑規則
取得積點的動作會伴隨著學生上傳作品或教師批閱作品時發生,而顯示使用者積點則預計在顯示修課名單時一併顯示每位學生目前所獲得的積點數量,所以不需另外定義其他路徑規則。
修改相關視圖類別
請開啟應用程式 course
的視圖定義檔 course/views.py
,依下述方式修改:
from user.models import Message, PointHistory
修課名單新增使用者積點統計
class CourseUsers(CourseAccessMixin, ListView):
permission = COURSE_PERM_MEMBER
extra_context = {'title': '修課名單'}
template_name = 'course/user_list.html'
def get_queryset(self):
return self.course.enroll_set.select_related('stu')\
.annotate(
points = Sum('stu__point_list__point')
).order_by('seat')
學生繳交作業(上傳作品)取得 2 個積點
修改 WorkSubmit
視圖類別,新增點數紀錄:
class WorkSubmit(CourseAccessMixin, CreateView):
extra_context = {'title': '繳交作業'}
permission = COURSE_PERM_STUDENT
model = Work
fields = ['memo', 'attachment']
template_name = 'form.html'
def form_valid(self, form):
form.instance.assignment = Assignment(id=self.kwargs['aid'])
form.instance.user = self.request.user
PointHistory(
user = form.instance.user,
assignment = form.instance.assignment,
reason = '繳交作業',
point = 2
).save()
return super().form_valid(form)
def get_success_url(self):
return reverse(
'assignment_view',
args=[self.course.id, self.object.assignment.id]
)
教師評分
修改 WorkScore
視圖類別,新增點數紀錄:
class WorkScore(CourseAccessMixin, UpdateView):
extra_context = {'title': '批改作業'}
permission = COURSE_PERM_TEACHER
model = Work
fields = ['score']
pk_url_kwarg = 'wid'
def get_success_url(self):
return reverse(
'assignment_view',
args=[self.course.id, self.object.assignment.id]
)
def get_form(self):
form = super().get_form()
form.fields['score'] = forms.ChoiceField(
label = '成績',
choices = [
(100, "你好棒(100分)"),
(90, "90分"),
(80, "80分"),
(70, "70分"),
(60, "60分"),
],
)
self.oldscore = self.object.score
return form
def form_valid(self, form):
def score_to_point(score):
return 2 if score >= 90 else 1 if score >= 80 else 0
oscore = self.oldscore
nscore = form.instance.score
opoint = score_to_point(oscore)
npoint = score_to_point(nscore)
if opoint != npoint:
PointHistory(
user = self.object.user,
assignment = self.object.assignment,
reason = f'教師評分: {oscore} -> {nscore}',
point = npoint - opoint,
).save()
return super().form_valid(form)
修改頁面範本
修課學生列表
開啟 templates/course/user_list.html
,新增第 12, 24 行:
<thead>
<tr>
<th>學校</th>
<th>帳號</th>
<th>座號</th>
<th>姓名</th>
<th>積分</th>
<th>最近登入時間</th>
{% for enroll in enroll_list %}
<tr>
<td>{{ enroll.stu.last_name }}</td>
<td>{{ enroll.stu.username }}</td>
<td>{{ enroll.seat }}</td>
<td>{{ enroll.stu.first_name }}</td>
<td>{{ enroll.points|default:0 }}</td>
<td>{{ enroll.stu.last_login|date:"Y-m-d H:i" }}</td>
使用者個人積分紀錄列表
修改檢視使用者頁面範本,插入第 18 - 32 行列出使用者積點紀錄清單:
{% endif %}
<div class="card-title">個人積點</div>
<ul>
{% for ph in tuser.point_list.all reversed %}
<li>
{{ ph.created|date:"Y-m-d H:i"}}
{{ ph.reason }}:
{% with aid=ph.assignment.id cid=ph.assignment.course.id %}
<a href="{% url 'assignment_view' cid aid %}">
{{ ph.assignment.title }}
</a>
{% endwith %}
<span class="badge badge-warning">{{ ph.point }}點</span>
</li>
{% endfor %}
</ul>
<div class="card-title">選修的課程</div>
- 第 20 行,以頁面範本的
{% for %}
標籤將 tuser.point_list.all
裡的每筆積點紀錄一一列出,最後面的 reversed
表示以相反順序處理清單,也就是由新往舊的順序列出。
- 第 24 行,頁面範本的
{% with %}
標籤也可以一次定義多個變數,變數的定義彼此以空格隔開即可。以此例來說,定義了 aid
與 cid
兩個變數以縮減第 25 行程式碼的長度。
積分管理
為了鼓勵學生繳交作業,在這個專案裡設計了一個積分的機制,讓學生以繳交作業來累積點數,在課程的修課名單中也會增加一個欄位顯示每位學生目前所獲取的點數,以期透過同儕間的競爭心理,激勵學生繳交作業。
學生每次繳交作業可以取得 2 個積點,當教師完成評分時,受評的學生的作業成績如果超過 90 分可以獲得額外的 2 個積點,超過 80 分可以獲得額外 1 個積點。
定義積分紀錄資料模型
直接將積分紀錄的資料模型定義在現存的應用程式內即可,這邊選擇將其定義在應用程式
user
之下。請開啟user/models.py
,修改第 3 行並新增第 35 - 47 行:Assignment
定義路徑規則
取得積點的動作會伴隨著學生上傳作品或教師批閱作品時發生,而顯示使用者積點則預計在顯示修課名單時一併顯示每位學生目前所獲得的積點數量,所以不需另外定義其他路徑規則。
修改相關視圖類別
請開啟應用程式
course
的視圖定義檔course/views.py
,依下述方式修改:PointHistory
資料模型修課名單新增使用者積點統計
學生繳交作業(上傳作品)取得 2 個積點
修改
WorkSubmit
視圖類別,新增點數紀錄:教師評分
修改
WorkScore
視圖類別,新增點數紀錄:修改頁面範本
修課學生列表
開啟
templates/course/user_list.html
,新增第 12, 24 行:使用者個人積分紀錄列表
修改檢視使用者頁面範本,插入第 18 - 32 行列出使用者積點紀錄清單:
{% for %}
標籤將tuser.point_list.all
裡的每筆積點紀錄一一列出,最後面的reversed
表示以相反順序處理清單,也就是由新往舊的順序列出。{% with %}
標籤也可以一次定義多個變數,變數的定義彼此以空格隔開即可。以此例來說,定義了aid
與cid
兩個變數以縮減第 25 行程式碼的長度。