CRM——講師與學生

1、課程記錄和學習記錄

1.初始化 course_record, study_record.
2.學習記錄
3.錄入成績
4.顯示成績 ajax 查詢 柱狀圖展現成績 highcharts

5.上傳做業(os模塊)
6.下載做業javascript

2、配置study_record

一、給學習記錄配置自定義配置

class StudyConfig(ModelStark):
    def display_record(self, obj=None, header=False):
        if header:
            return "簽到"
        return obj.get_record_display()     # 存的值對應的中文

    def display_score(self, obj=None, header=False):
        if header:
            return "成績"
        return obj.get_score_display()     # 存的值對應的中文

    list_display = ["student", "course_record", display_record, display_score]

site.register(StudyRecord, StudentConfig)

  不取字段值而是拼上get和display取存的值對應的中文。css

二、修改ModelStark中get_body方法全局處理記錄對象包含choices狀況

  在models中choices對應的是一個元組。html

class ShowList(object):
    """展現頁面類"""
    def get_body(self):
        """構建表單數據"""
        """代碼省略"""
            # 針對choices屬性
            if field_obj.choices:
                val = getattr(obj, "get_" + field + "_display")
            else:
                val = getattr(obj, field)   # 拿到的關聯對象  處理不了多對多

##################自定義配置#############
class StudyConfig(ModelStark):
    list_display = ["student", "course_record", "record", "score"]

site.register(StudyRecord, StudentConfig)

  錄入學習記錄:java

  

3、批量生成學習記錄

一、定製CourseRecod批量功能

class CourseRecordConfig(ModelStark):
    list_display = ["class_obj", "day_num", "teacher"]

    def patch_studyRecord(self, request, queryset):
        print("=====>",queryset)
        """
        提交批量操做獲取的queryset
        <QuerySet [<CourseRecord: python基礎(9期) day94>, <CourseRecord: python基礎(9期) day95>]>
        """
        temp = []
        for course_record in queryset:
            # 過濾出班級全部的學生  學生表classlist關聯班級表
            student_list = Student.objects.filter(class_list__id=course_record.class_obj.pk)   # 學生的班級id和課程記錄班級的id進行比對  拿到班級全部的學生
            for student in student_list:   # 拿到學生對象
                obj = StudyRecord(student=student, course_record=course_record)
                temp.append(obj)

        StudyRecord.objects.bulk_create(temp)   # 批量插入

    actions = [patch_studyRecord, ]
    patch_studyRecord.short_description = "批量生產學習記錄"
    """
    def get_action_list(self):
        # 獲取自定義批量操做
        temp = []
        for action in self.actions:
            temp.append({
                "name": action.__name__,    # 函數.__name__:拿到函數名
                "desc": action.short_description
            })  # [{"name": "patch_init", "desc": "批量處理"}]
        return temp
    """

site.register(CourseRecord, CourseRecordConfig)

  注意python

(1)批量插入操做:jquery

StudyRecord.objects.bulk_create(temp)

(2)跨表查詢班級全部的學生ajax

# 過濾出班級全部的學生  學生表classlist關聯班級表
student_list = Student.objects.filter(class_list__id=course_record.class_obj.pk)   # 學生的班級id和課程記錄班級的id進行比對  拿到班級全部的學生

  過濾course_record關聯的班級對應的全部的學生。django

(3)批量操做別名描述short_descriptionbootstrap

  這是因爲在Modelstark中源碼get_action_list有關於action別名的配置:數組

def get_action_list(self):
    # 獲取自定義批量操做
    temp = []
    for action in self.actions:
        temp.append({
            "name": action.__name__,    # 函數.__name__:拿到函數名
            "desc": action.short_description
        })  # [{"name": "patch_init", "desc": "批量處理"}]
    return temp

二、批量生成學習記錄

  

  學習記錄生產成功:

  

4、學習記錄篩選查看

一、studyrecord/?course_record=%s過濾

  根據課程記錄來過濾學習記錄,這個須要修改service/stark.py中的get_filter_condition。由於這個其實也是一種filter過濾,但並無寫在filter_list中。

class ModelStark(object):
    def get_filter_condition(self, request):
        """拿到過濾條件"""
        filter_condition = Q()  # 默認查詢條件爲且 and

        for filter_field, val in request.GET.items():   # 過濾字段、查詢的值  去除fitler_field拼接的__id
            # if filter_field in self.list_filter:  # 僅限過濾使用,只處理filter過濾列表的鍵值
            if filter_field != "page":   # (分頁等排除)  ?page=2&course_record=1
                filter_condition.children.append((filter_field, val))   # 添加的是一個元組

        return filter_condition

  修改後僅排除了?page=1這樣的狀況,能夠在頁面上訪問http://127.0.0.1:8000/stark/crm/studyrecord/?course_record=2拿到過濾結果:

  

二、添加按鈕實現條件過濾查看

class CourseRecordConfig(ModelStark):
    # 定製一欄新的表格
    def record(self, obj=None, header=False):
        if header:
            return "checked"
        return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>記錄</a>" % obj.pk)    # mark_safe取消轉義

    list_display = ["class_obj", "day_num", "teacher", record]

    def patch_studyRecord(self, request, queryset):
        temp = []
        for course_record in queryset:
            # 過濾course_record關聯的班級對應的全部的學生  學生表classlist關聯班級表
            student_list = Student.objects.filter(class_list__id=course_record.class_obj.pk)   # 學生的班級id和課程記錄班級的id進行比對  拿到班級全部的學生
            for student in student_list:   # 拿到學生對象
                obj = StudyRecord(student=student, course_record=course_record)
                temp.append(obj)
        StudyRecord.objects.bulk_create(temp)   # 批量插入

    actions = [patch_studyRecord, ]
    patch_studyRecord.short_description = "批量生產學習記錄"

site.register(CourseRecord, CourseRecordConfig)

  課程記錄頁面:

  

  點擊記錄跳轉學習記錄頁面:

  

5、考勤點名

  給學習記錄訂製遲到批量操做

class StudyConfig(ModelStark):
    list_display = ["student", "course_record", "record", "score"]
    def patch_late(self, request, queryset):
        queryset.update(record="late")

    patch_late.short_description = "遲到"
    actions = [patch_late, ]

site.register(StudyRecord, StudyConfig)

  批量調整上課記錄爲遲到:

  

6、錄入成績

一、在課程記錄頁面添加錄入成績欄(擴展新的url)

class CourseRecordConfig(ModelStark):
    def score(self, request, course_record_id):
        return HttpResponse("score")

    def extra_url(self):
        """擴展考勤記錄url"""
        temp = []
        temp.append(url(r"record_score/(\d+)", self.score))
        return temp

    # 定製一欄新的表格
    def record(self, obj=None, header=False):
        if header:
            return "考勤"
        return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>記錄</a>" % obj.pk)    # mark_safe取消轉義

    def record_score(self, obj=None, header=False):
        if header:
            return "錄入成績"
        # http://127.0.0.1:8000/stark/crm/studyrecord/?course_record=1  CourseRecord主鍵值
        return mark_safe("<a href='record_score/%s'>錄入成績</a>" % obj.pk)

    list_display = ["class_obj", "day_num", "teacher", record, record_score]
    
    def patch_studyRecord(self, request, queryset):
        """代碼省略"""

 注意:

(1)定製record_score函數添加錄入成績項目欄

def record_score(self, obj=None, header=False):
    if header:
        return "錄入成績"
    # http://127.0.0.1:8000/stark/crm/studyrecord/?course_record=1  CourseRecord主鍵值
    return mark_safe("<a href='record_score/%s'>錄入成績</a>" % obj.pk)

(2)定製錄入成績擴展路由和視圖

def score(self, request, course_record_id):
    return HttpResponse("score")

def extra_url(self):
    """擴展考勤記錄url"""
    temp = []
    temp.append(url(r"record_score/(\d+)", self.score))
    return temp

(3)測試驗證

  

  點擊錄入成績,跳轉對應頁面:

  

二、處理score視圖函數

class CourseRecordConfig(ModelStark):
    def score(self, request, course_record_id):
        study_record_list = StudyRecord.objects.filter(course_record=course_record_id)   # 過濾出對應課程(哪一個班級哪一天)的學習記錄

        score_choices = StudyRecord.score_choices
        return render(request, "score.html", locals())

注意:

(1)study_record_list拿到對應課程的學習記錄(哪一天哪一個班級)

(2)score_choices拿到StudyRecord的score_choices字段內容傳遞給模板

三、構建錄入成績頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery-1.12.4.min.js"></script>
</head>
<body>
<h3>錄入成績</h3>
<div class="container">
    <div class="row">
        <div class="col-md-9 col-md-offset-1">
            <form action="" method="post">
                {% csrf_token %}
                <table class="table table-bordered table-striped">
                <thead>
                    <tr>
                        <th>學生姓名</th>
                        <th>考勤</th>
                        <th>成績</th>
                        <th>批語</th>
                    </tr>
                </thead>
                <tbody>
                    {% for study_record in study_record_list %}
                        <tr>
                            <td>{{ study_record.student }}</td>
                            {# <td>{{ study_record.record }}</td>   針對帶有choices的字段使用拼接get和display #}
                            <td>{{ study_record.get_record_display }}</td>
                            <td style="width: 150px; padding: 10px 20px;">
                                <select name="" id="" class="form-control">
                                    {% for item in score_choices %}
                                        <option value="{{ item.0 }}">{{ item.1 }}</option>
                                    {% endfor %}
                                </select>
                            </td>
                            <td>
                                <textarea name="" id="" cols="30" rows="4" class="form-control"></textarea>
                            </td>
                        </tr>
                    {% endfor %}

                </tbody>
            </table>
                <input type="submit" class="btn btn-default pull-right">
            </form>
        </div>
    </div>
</div>
</body>
</html>
score.html

注意:

(1)考勤欄顯示中文

  針對Model中的record字段:

record = models.CharField("上課紀錄", choices=record_choices, default="checked", max_length=64)

  要顯示遲到簽到信息須要拼接get和display取值

{# <td>{{ study_record.record }}</td>   針對帶有choices的字段使用拼接get和display #}
<td>{{ study_record.get_record_display }}</td>

  顯示效果:

  

(2)成績顯示爲一個個option對象點選操做

<td style="width: 150px; padding: 10px 20px;">
    <select name="score" id="" class="form-control">
        {% for item in score_choices %}
            <option value="{{ item.0 }}">{{ item.1 }}</option>
        {% endfor %}
    </select>
</td>

  item.0拿到score_choices中每一個元組的第一個值即分數,item.1拿到元組第二個值即評分等級。顯示效果以下:

  

(3)用textarea渲染批語欄

<td>
    <textarea name="homework_note" id="" cols="30" rows="4" class="form-control"></textarea>
</td>

  顯示效果以下所示:

  

(4)訂製表單和提交按鈕

<body>
<h3>錄入成績</h3>
<div class="container">
    <div class="row">
        <div class="col-md-9">
            <form action="" method="post">
                {% csrf_token %}
                <table class="table table-bordered table-striped"....>
                <input type="submit" class="btn btn-default pull-right">
            </form>
        </div>
    </div>
</div>
</body>

  顯示效果:

  

四、視圖函數處理post請求

class CourseRecordConfig(ModelStark):
    def score(self, request, course_record_id):
        if request.method == "POST":
            # print(request.POST)
            # <QueryDict: {'csrfmiddlewaretoken': ['20Zp72PlKJzRZ6HAYkMX0veCIxynx5nogd8LsKKkdZb7mRLrAb1KtN1PDTljh7Jq'], 'score_4': ['70'], 'homework_note_4': ['學習理解能力差'], 'score_5': ['40'], 'homework_note_5': ['無紀律無組織'], 'score_6': ['90'], 'homework_note_6': ['學習能力優秀']}>
            for key, value in request.POST.items():
                if key == "csrfmiddlewaretoken":
                    continue
                # 分隔score_1爲例,score爲字段  1爲某一個學生學習記錄的pk值
                field, pk = key.rsplit("_", 1)  # 從右開始以"_"分隔數據,且僅分隔一次
                if field == "score":
                    StudyRecord.objects.filter(pk=pk).update(score=value)
                else:
                    StudyRecord.objects.filter(pk=pk).update(homework_note=value)
            return redirect(request.path)  # 拿到當前POST請求路徑重定向GET請求
        else:
            study_record_list = StudyRecord.objects.filter(course_record=course_record_id)   # 過濾出對應課程(哪一個班級哪一天)的學習記錄

            score_choices = StudyRecord.score_choices
            return render(request, "score.html", locals())

  同時還伴隨有score.html的變動:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery-1.12.4.min.js"></script>
</head>
<body>
<h3>錄入成績</h3>
<div class="container">
    <div class="row">
        <div class="col-md-9 col-md-offset-1">
            <form action="" method="post">
                {% csrf_token %}
                <table class="table table-bordered table-striped">
                    <thead>
                    <tr>
                        <th>學生姓名</th>
                        <th>考勤</th>
                        <th>成績</th>
                        <th>批語</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for study_record in study_record_list %}
                        <tr>
                            <td>{{ study_record.student }}</td>
                            {# <td>{{ study_record.record }}</td>   針對帶有choices的字段使用拼接get和display #}
                            <td>{{ study_record.get_record_display }}</td>
                            <td style="width: 150px; padding: 10px 20px;">
                                <select name="score_{{ study_record.pk }}" id="" class="form-control">
                                    {% for item in score_choices %}
                                        {% if study_record.score == item.0 %}
                                            {# 當前成績等於item.0#}
                                            <option selected value="{{ item.0 }}">{{ item.1 }}</option>
                                        {% endif %}
                                        <option value="{{ item.0 }}">{{ item.1 }}</option>
                                    {% endfor %}
                                </select>
                            </td>
                            <td>
                                <textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="4"
                                          class="form-control">{{ study_record.homework_note }}</textarea>
                            </td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
                <input type="submit" class="btn btn-default pull-right">
            </form>
        </div>
    </div>
</div>
</body>
</html>
View Code

(1)分析表單提交的數據

  直接在上面的成績錄入頁面提交POST請求:

  

  在視圖中接收POST請求,打印接收的request.POST數據:

class CourseRecordConfig(ModelStark):
    def score(self, request, course_record_id):
        if request.method == "POST":
            print(request.POST)
            """
            <QueryDict: {'csrfmiddlewaretoken': ['UMfON3mW1TKIMCqWI3fqOUuRaqP9ggoL8Zoa8LhVu9mY9nuNkUudhch45MC50iKN'], 
            'score': ['60', '80', '90'], 'homework_note': ['朽木不可雕', '學習自覺性較差', '學習認真刻苦']}>
            """
            return HttpResponse("123")

  這是因爲全部的成績select標籤name="score",全部批語textarea標籤name="homework_note",一個鍵對應三個值,三個值組成數組。致使沒法區分誰是誰的成績和批語。

(2)修改select標籤和textarea標籤name生成規則

<td style="width: 150px; padding: 10px 20px;">
    <select name="score_{{ study_record.pk }}" id="" class="form-control">
        {% for item in score_choices %}
            <option value="{{ item.0 }}">{{ item.1 }}</option>
        {% endfor %}
    </select>
</td>
<td>
    <textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="4" class="form-control"></textarea>
</td>

  從新提交表單,request.POST獲取的數據以下:

class CourseRecordConfig(ModelStark):
    def score(self, request, course_record_id):
        if request.method == "POST":
            print(request.POST)
            # <QueryDict: {'csrfmiddlewaretoken': ['20Zp72PlKJzRZ6HAYkMX0veCIxynx5nogd8LsKKkdZb7mRLrAb1KtN1PDTljh7Jq'], 'score_4': ['70'], 'homework_note_4': ['學習理解能力差'], 'score_5': ['40'], 'homework_note_5': ['無紀律無組織'], 'score_6': ['90'], 'homework_note_6': ['學習能力優秀']}>

  如上所示鍵帶有本身的id值,能夠更好地去錄入成績,完成處理更新操做。

(3)splice()和rsplice方法

  Python split() 經過指定分隔符對字符串進行切片,若是參數 num 有指定值,則僅分隔 num 個子字符串。

print("yuan_alex_egon".split("_", 1))   # 只分一次
print("yuan_alex_egon".split("_", 2))   # 分兩次
print("yuan_alex_egon".rsplit("_",1))   # 從右邊開始分一次
"""
['yuan', 'alex_egon']
['yuan', 'alex', 'egon']
['yuan_alex', 'egon']
"""

(4)循環處理reques.POST

for key, value in request.POST.items():
    if key == "csrfmiddlewaretoken":
        continue
    # 分隔score_1爲例,score爲字段  1爲某一個學生學習記錄的pk值
    field, pk = key.rsplit("_", 1)  # 從右開始以"_"分隔數據,且僅分隔一次
    if field == "score":
        StudyRecord.objects.filter(pk=pk).update(score=value)
    else:
        StudyRecord.objects.filter(pk=pk).update(homework_note=value)

(5)重定向到POST請求當前頁面

def score(self, request, course_record_id):
    if request.method == "POST":
        """代碼省略"""
        return redirect(request.path)  # 拿到當前POST請求路徑重定向GET請求

(6)get頁面渲染顯示以前提交信息爲默認值

<td style="width: 150px; padding: 10px 20px;">
    <select name="score_{{ study_record.pk }}" id="" class="form-control">
        {% for item in score_choices %}
            {% if study_record.score == item.0 %}
            {# 當前成績等於item.0#}
                <option selected value="{{ item.0 }}">{{ item.1 }}</option>
            {% endif %}
            <option value="{{ item.0 }}">{{ item.1 }}</option>
        {% endfor %}
    </select>
</td>
<td>
    <textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="4" class="form-control">{{ study_record.homework_note }}</textarea>
</td>

  這樣在POST請求提交後,get請求獲取的當前頁面,頁面保留以前錄入的數據。

五、數據結構調整性能優化

class CourseRecordConfig(ModelStark):
    def score(self, request, course_record_id):
        if request.method == "POST":
            data = {}
            for key, value in request.POST.items():   # 鍵、值
                if key == "csrfmiddlewaretoken":
                    continue
                # 分隔score_1爲例,score爲字段  1爲某一個學生學習記錄的pk值
                field, pk = key.rsplit("_", 1)  # 從右開始以"_"分隔數據,且僅分隔一次   字段、主鍵

                # dic = {1:{"homework_note":"", "score":90}, 2:{"homework_note": "", "score": 76}}
                if pk in data:
                    # 第一次加入字典
                    data[pk][field] = value
                else:
                    # pk已經保存在字典中
                    data[pk] = {field: value}

            print("data", data)  # data {'4': {'score': '100', 'homework_note': 'dsfe '}, '5': {'score': '85', 'homework_note': 'asd a'}, '6': {'score': '50', 'homework_note': 'adad w'}}

            for pk, update_data in data.items():   # 主鍵、更新數據
                StudyRecord.objects.filter(pk=pk).update(**update_data)

            return redirect(request.path)  # 拿到當前POST請求路徑重定向GET請求

(1)將數據調整爲字典套字典的格式

def score(self, request, course_record_id):
    if request.method == "POST":
        data = {}
        for key, value in request.POST.items():   # 鍵、值
            if key == "csrfmiddlewaretoken":
                continue
            # 分隔score_1爲例,score爲字段  1爲某一個學生學習記錄的pk值
            field, pk = key.rsplit("_", 1)  # 從右開始以"_"分隔數據,且僅分隔一次   字段、主鍵

            # dic = {1:{"homework_note":"", "score":90}, 2:{"homework_note": "", "score": 76}}
            if pk in data:
                # 第一次加入字典
                data[pk][field] = value
            else:
                # pk已經保存在字典中
                data[pk] = {field: value}

        print("data", data)  # data {'4': {'score': '100', 'homework_note': 'dsfe '}, '5': {'score': '85', 'homework_note': 'asd a'}, '6': {'score': '50', 'homework_note': 'adad w'}}

(2)更新數據

for pk, update_data in data.items():   # 主鍵、更新數據
    StudyRecord.objects.filter(pk=pk).update(**update_data)

  update()方法對於任何結果集均有效,能夠同時更新多條記錄。

7、顯示成績 ajax 查詢 柱狀圖展現成績 highcharts

一、給學生表定製成績查詢(擴展視圖和url)

class StudentConfig(ModelStark):
    def score_view(self, request, sid):   # sid:當前學生的id
        """擴展視圖"""
        student = Student.objects.filter(pk=sid).first()
        class_list = student.class_list.all()     # 班級列表
        return render(request, "score_view.html", locals())

    def extra_url(self):
        """擴展路由"""
        temp = []
        temp.append(url((r"score_view/(\d+)"), self.score_view))
        return temp

    def score_show(self, obj=None, header=False):
        """查當作績"""
        if header:
            return "查當作績"
        return mark_safe("<a href='/stark/crm/student/score_view/%s'>查當作績</a>" % obj.pk)

    list_display = ['customer', 'class_list', score_show]
    list_display_links = ['customer']

site.register(Student, StudentConfig)

  顯示效果:

  

二、成績展現模板設計

  score_view.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery-1.12.4.min.js"></script>
</head>
<body>
<h3>查看{{ student }}成績</h3>
<div class="container">
    <div class="row">
        <div class="col-md-9 col-md-offset-1">
            <table class="table table-bordered table-striped">
                <thead>
                <tr>
                    <th>班級</th>
                    <th>班主任</th>
                    <th>任課老師</th>
                    <th>課程成績</th>
                </tr>
                </thead>
                <tbody>
                    {% for cls in class_list %}
                        <tr>
                            {# 班級名稱:class_list.__str__ #}
                            <td>{{ cls }}</td>
                            <td>{{ cls.tutor }}</td>
                            <td>
                                {% for teacher in cls.teachers.all %}
                                    <span>{{ teacher }}</span>,
                                {% endfor %}
                            </td>
                            <td>
                                <a class="check_chart"><span>點擊查看</span></a>
                            </td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>

  展現效果:

  

三、給點擊查看綁定事件

<script>
    // check_chart綁定事件
    $(".check_chart").click(function () {
        $.ajax({
            url: "",   // 走當前
            type: "get",
            data:{
                sid: $(this).attr("sid"),
                cid: $(this).attr("cid"),
            },
            success:function (data) {
                console.log(data);
            }
        })
    })
</script>

(1)給點擊查看a標籤添加sid和cid屬性

<td>
    <a class="check_chart" cid="{{ cls.pk }}" sid="{{ student.pk }}"><span>點擊查看</span></a>
</td>

  其中sid是學生id,cid是班級id。

(2)給視圖發送ajax,獲取學生對應課程的全部學習記錄

class StudentConfig(ModelStark):
    def score_view(self, request, sid):   # sid:當前學生的id
        """擴展視圖"""
        if request.is_ajax():
            # 處理ajax請求
            print(request.GET)
            sid = request.GET.get("sid")
            cid = request.GET.get("cid")
            # 去studyrecord查看學生對應課程全部學習記錄  課程須要跨表查詢
            study_record_list = StudyRecord.objects.filter(student=sid, course_record__class_obj=cid)
        else:
            student = Student.objects.filter(pk=sid).first()
            class_list = student.class_list.all()     # 班級列表
            return render(request, "score_view.html", locals())

四、使用highchart插件顯示成績

(1)下載引入highchart

  地址:https://www.hcharts.cn下載程序包後,將壓縮包下code文件夾拷貝到項目crm/static目錄下,並更名爲chart.

  

  在score_view.html中引入highcharts.js:

<head>
    #省略#
    <script src="/static/chart/highcharts.js"></script>
</head>

(2)設計柱狀圖

  

(3)將顯示柱狀圖放入ajax中處理

<body>
<h3>查看{{ student }}成績</h3>
<div class="container"...>
<div id="container" style="min-width:400px;height:400px"></div>
<script>
    // check_chart綁定事件
    $(".check_chart").click(function () {
        $.ajax({
            url: "",   // 走當前
            type: "get",
            data: {
                sid: $(this).attr("sid"),
                cid: $(this).attr("cid"),
            },
            success: function (data) {
                // 顯示柱狀圖
                var chart = Highcharts.chart('container', {
                    chart: {
                        type: 'column'
                    },
                    title: {
                        text: '查當作績'
                    },
                    subtitle: {
                        text: '數據截止 2017-03,來源: <a href="https://en.wikipedia.org/wiki/List_of_cities_proper_by_population">Wikipedia</a>'
                    },
                    xAxis: {   // 橫座標
                        type: 'category',
                        labels: {
                            rotation: -45  // 設置軸標籤旋轉角度
                        }
                    },
                    yAxis: {   // 縱座標
                        min: 0,
                        title: {
                            text: '分數'
                        }
                    },
                    legend: {
                        enabled: false
                    },
                    tooltip: {   // 鼠標懸浮顯示
                        pointFormat: '分數: <b>{point.y:.2f}</b>'
                    },
                    series: [{
                        name: '成績',
                        data: data,
                        dataLabels: {
                            enabled: true,
                            rotation: -90,
                            color: '#FFFFFF',
                            align: 'right',
                            format: '{point.y:.1f}', // :.1f 爲保留 1 位小數
                            y: 10
                        }
                    }]
                });
            }
        })
    })
</script>
</body>

五、在視圖處理出highcharts模板要求的data數據

from django.http import JsonResponse

class StudentConfig(ModelStark):
    def score_view(self, request, sid):   # sid:當前學生的id
        """擴展視圖"""
        if request.is_ajax():
            # 處理ajax請求
            print(request.GET)
            sid = request.GET.get("sid")
            cid = request.GET.get("cid")
            # 去studyrecord查看學生對應課程全部學習記錄  課程須要跨表查詢
            study_record_list = StudyRecord.objects.filter(student=sid, course_record__class_obj=cid)

            data_list = []
            for study_record in study_record_list:
                day_num = study_record.course_record.day_num  # 天數
                data_list.append(["day%s" % day_num, study_record.score])    # 和highchart的data要求格式相同列表包列表
            print(data_list)   # [['day1', -1], ['day95', 80]]
            return JsonResponse(data_list, safe=False)  # 序列化不是一個字典必須改成False
        else:

            student = Student.objects.filter(pk=sid).first()
            class_list = student.class_list.all()     # 班級列表
            return render(request, "score_view.html", locals())

  注意要將數據組織爲 [['day94', 100], ['day95', 50], ['day92', 85], ['day91', 90]] 這樣的形式。且使用JsonResponse進行序列化,在系列化的不是一個字典時,須要修改safe=False。

六、顯示效果

  

相關文章
相關標籤/搜索