一、讲师与学生简介

1 初始化 course_record,studyrecord,

2 考勤

3 录入成绩

4 显示成绩 ajax 查询

5 上传作业(os模块)

6 下载作业

二、 初始化 ,studyrecord,

1、生成studyrecord

2、批量初始化迟到

class StudyRecordConfig(ModelStark):

    def patch_late(self, request, queryset):
queryset.update(record='late') patch_late.short_description = '迟到'
actions = [patch_late] site.register(StudyRecord, StudyRecordConfig)

3、get_field_display()

class StudyRecordConfig(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] def patch_late(self, request, queryset):
queryset.update(record='late') patch_late.short_description = '迟到'
actions = [patch_late] site.register(StudyRecord, StudyRecordConfig)

三、初始化 course_record:批量生成学习记录

1、生成course_record

2、批量生成学习记录

class CourseRecordConfig(ModelStark):

    def patch_studyrecord(self, request, queryset):
print(queryset) # <QuerySet [<CourseRecord: python基础班(9期) day11>]>
temp = []
for course_record in queryset:
student_list = Student.objects.filter(class_list=course_record.class_obj.pk)
for student in student_list:
obj = StudyRecord(student=student, course_record=course_record)
temp.append(obj) StudyRecord.objects.bulk_create(temp) # 批量生成数据 patch_studyrecord.short_description = '批量生成学习记录'
actions = [patch_studyrecord, ] site.register(CourseRecord, CourseRecordConfig)

四、 考勤  url跳转

1. ?course_record=%s 过滤;

from django.utils.safestring import mark_safe

class CourseRecordConfig(ModelStark):

    def record(self, obj=None, header=False):
if header:
return '学习记录'
return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>" % (obj.pk)) list_display = ['class_obj', 'day_num', 'teacher', record] site.register(CourseRecord, CourseRecordConfig)

全局修改

2、 mark_safe

from django.utils.safestring import mark_safe
return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>" % (obj.pk))

五、录入成绩

代码

class CourseRecordConfig(ModelStark):
def score(self, request, course_record_id):
"""录入成绩view"""
study_record_list = StudyRecord.objects.filter(course_record=course_record_id)
print(study_record_list)
score_choices = StudyRecord.score_choices
if request.method == "POST":
print(request.POST) # <QueryDict: 'score_4': ['100'], 'homeword_note_4': ['33']}> data = {} # dic = {1:{'homework_note':'good','score':'90'},2:{'homework_note':'nonono','score':'80'},} for key, value in request.POST.items():
if key == "csrfmiddlewaretoken": continue
field, pk = key.rsplit('_', 1) if pk in data:
data[pk][field] = value
else:
data[pk] = {field: value} print('data', data) for pk, val in data.items():
StudyRecord.objects.filter(pk=pk).update(**val) '''
# 方式1
if field == 'score':
StudyRecord.objects.filter(pk=pk).update(score=value)
else:
StudyRecord.objects.filter(pk=pk).update(homework_note=value.strip())
''' return redirect(request.path) # 跳转到当前url return render(request, 'score.html', locals()) def extra_url(self):
"""录入成绩url"""
temp = []
temp.append(url('record_score/(\d+)', self.score))
return temp def record_score(self, obj=None, header=False):
"""录入成绩a标签"""
if header:
return "录入成绩"
return mark_safe("<a href='record_score/%s'>录入成绩</a>" % (obj.pk)) list_display = ['class_obj', 'day_num', 'teacher', record_score] site.register(CourseRecord, CourseRecordConfig)

知识点

1、mark_safe

    def record_score(self, obj=None, header=False):
"""录入成绩a标签"""
if header:
return "录入成绩"
return mark_safe("<a href='record_score/%s'>录入成绩</a>" % (obj.pk))

2、添加额外的 extra_url

    def extra_url(self):
"""录入成绩url"""
temp = []
temp.append(url('record_score/(\d+)', self.score))
return temp

全局修改

3、form表单提交数据

class CourseRecordConfig(ModelStark):
def score(self, request, course_record_id):
"""录入成绩view"""
if request.method == "POST":
print(request.POST) # <QueryDict: 'score_4': ['100'], 'homeword_note_4': ['33']}>

4、处理数据( field, pk = key.rsplit('_', 1) )

      data = {}  

            for key, value in request.POST.items():
if key == "csrfmiddlewaretoken": continue
field, pk = key.rsplit('_', 1) if pk in data:
data[pk][field] = value
else:
data[pk] = {field: value} print('data', data)
# dic = {1:{'homework_note':'good','score':'90'},2:{'homework_note':'nonono','score':'80'},}

5、更新数据

                for pk, val in data.items():
StudyRecord.objects.filter(pk=pk).update(**val) '''
# 方式1
if field == 'score':
StudyRecord.objects.filter(pk=pk).update(score=value)
else:
StudyRecord.objects.filter(pk=pk).update(homework_note=value.strip())
'''

6、跳转到当前页面

return redirect(request.path)  # 跳转到当前url

7、get请求

        study_record_list = StudyRecord.objects.filter(course_record=course_record_id)
print(study_record_list)
score_choices = StudyRecord.score_choices
     return render(request, 'score.html', locals())

8、上传数据

                              <select name="score_{{ study_record.pk }}" class="form-control">
{% for item in score_choices %}
{% if study_record.score == item.0 %}
<option selected value="{{ item.0 }}">{{ item.1 }}</option>
{% endif %}
<option value="{{ item.0 }}">{{ item.1 }}</option> {% endfor %} </select> <textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="3"
class="form-control">
{{ study_record.homework_note }}
</textarea>

9、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.get_record_display }}</td>
<td style="width: 150px;padding: 10px 20px">
<select name="score_{{ study_record.pk }}" class="form-control">
{% for item in score_choices %}
{% if study_record.score == item.0 %}
<option selected value="{{ item.0 }}">{{ item.1 }}</option>
{% endif %}
<option value="{{ item.0 }}">{{ item.1 }}</option> {% endfor %} </select>
</td>
<td>
{{ study_record.homework_note }}
{% if study_record.homework_note %}
<textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="3"
class="form-control">
{{ study_record.homework_note }}
</textarea>
{% else %}
<textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="3"
class="form-control"></textarea>
{% endif %} </td> </tr>
{% endfor %} </tbody>
</table>
<input type="submit" class="btn btn-success pull-right">
</form>
</div> </div>
</div>
</body>
</html>

六、highcharts表的应用

官网 https://www.hcharts.cn/

1、应用

2、下载中心,cdn服务

使用我们提供的 CDN 服务(免下载,高速、稳定)

您可以直接使用我们的 CDN 文件而不用下载,速度快和稳定是我们的 CDN 服务的优势

// Highcharts
<script src="https://cdn.hcharts.cn/highcharts/highcharts.js"></script> // Highstock
<script src="https://cdn.hcharts.cn/highstock/highstock.js"></script> // Highmaps
<script src="https://cdn.hcharts.cn/highmaps/highmaps.js"></script>

更多文件详见 简数 CDN

3、如何使用

1-导入code

2-引入js

3-引入html代码
4-引入js代码
5-替换data

七、 student学生表,显示成绩(ajax)

class StudentConfig(ModelStark):
def score_view(self, request, stu_id):
"""查看成绩 view"""
if request.is_ajax():
cid = request.GET.get('cid')
sid = request.GET.get('sid') print(cid,sid)
study_record_list = StudyRecord.objects.filter(student=sid,course_record__class_obj=cid) print('study_record_list',study_record_list) # 方案1:构造数据 # [['day11', 85], ['day12', 90]]
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]) print('data_list',data_list) #方案2:构造数据 dic = {day:[day11,day12],score:[85,90]}
dic = {'day':[],'score':[]}
for study_record in study_record_list:
day_num = study_record.course_record.day_num
dic['day'].append('day%s'%day_num)
dic['score'].append(study_record.score)
print(dic)
print(dic['day'])
print(dic['score'])
return JsonResponse(dic,safe=False) else:
student = Student.objects.filter(pk=stu_id).first()
class_list = student.class_list.all()
return render(request, 'score_view.html', locals()) def extra_url(self):
"""查看成绩url"""
temp = []
temp.append(url(r"score_view/(\d+)", self.score_view))
return temp def score_show(self, obj=None, header=False):
"""查看成绩 a标签"""
if header:
return "查看成绩"
return mark_safe('<a href="score_view/%s">查看成绩</a>' % (obj.pk)) list_display = ['customer', 'class_list', score_show]
list_display_links = ['customer'] site.register(Student, StudentConfig)
知识点

1、 查看成绩a标签

    def score_show(self, obj=None, header=False):
"""查看成绩 a标签"""
if header:
return "查看成绩"
return mark_safe('<a href="score_view/%s">查看成绩</a>' % (obj.pk)) list_display = ['customer', 'class_list', score_show]

2、扩展url

    def extra_url(self):
"""查看成绩url"""
temp = []
temp.append(url(r"score_view/(\d+)", self.score_view))
return temp

3、view视图

    def score_view(self, request, stu_id):
"""查看成绩 view""" student = Student.objects.filter(pk=stu_id).first()
class_list = student.class_list.all()
return render(request, 'score_view.html', locals())

4、request.is_ajax

        if request.is_ajax():
cid = request.GET.get('cid')
sid = request.GET.get('sid') print(cid,sid)

5、跨表查询

            study_record_list = StudyRecord.objects.filter(student=sid,course_record__class_obj=cid)

            print('study_record_list',study_record_list)
# study_record_list <QuerySet [<StudyRecord: python基础班(9期) day11-liang>, <StudyRecord: python基础班(9期) day12-liang>]>

6、构造数据

            # 方案1:构造数据 # [['day11', 85], ['day12', 90]]
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]) print('data_list',data_list) #方案2:构造数据 dic = {day:[day11,day12],score:[85,90]}
dic = {'day':[],'score':[]}
for study_record in study_record_list:
day_num = study_record.course_record.day_num
dic['day'].append('day%s'%day_num)
dic['score'].append(study_record.score)
print(dic)
print(dic['day'])
print(dic['score'])

7、JsonResponse

返回JsonResponse,非字典需要加上 safe = False
from django.http import JsonResponse
return JsonResponse(data_list,safe=False)

8、前端显示table

            {% for cls in class_list %}
<tr>
<td>{{ cls }}</td>
<td>{{ cls.tutor }}</td>
<td>
{% for teacher in cls.teachers.all %}
<span>{{ teacher }}</span>
{% endfor %} </td>
<td><a class="check_chart" cid="{{ cls.pk }}" sid="{{ student.pk }}">点击查看</a>
</td>
</tr>
{% endfor %}

9、ajax的get提交

<script type="text/javascript">
$('.check_chart').click(function () {
$.ajax({
url: '',
type: 'get',
data: {
cid: $(this).attr('cid'),
sid: $(this).attr('sid')
},
success: function (data) {
console.log(data)
}
})
})
</script>

10、插入highchart代码

11、前端代码score_view.html

注意:cid sid 用法; ajax 显示 highcharts 柱状图
<a class="check_chart" cid="{{ cls.pk }}" sid="{{ student.pk }}">查看成绩</a>
<!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>
<script src="/static/charts/highcharts.js"></script>
</head>
<body>
<h3>查看{{ student }}成绩</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 cls in class_list %}
<tr>
<td>{{ cls }}</td>
<td>{{ cls.tutor }}</td>
<td>
{% for teacher in cls.teachers.all %}
<span>{{ teacher }}</span>
{% endfor %} </td>
<td><a class="check_chart" cid="{{ cls.pk }}" sid="{{ student.pk }}">点击查看</a>
</td>
</tr>
{% endfor %} </tbody>
</table>
</form> <div id="container" style="min-width:400px;height:400px"></div>
</div> </div>
</div> <script type="text/javascript">
$('.check_chart').click(function () {
$.ajax({
url: '',
type: 'get',
data: {
cid: $(this).attr('cid'),
sid: $(this).attr('sid')
},
success: function (data) {
{# console.log(data)#}
{# console.log(data['day'])#}
//显示chart图表
var chart = Highcharts.chart('container', {
chart: {
type: 'line'
},
title: {
text: '该学生的成绩记录'
},
subtitle: {
text: '数据来源: WorldClimate.com'
},
xAxis: {
categories: data['day']
},
yAxis: {
title: {
text: '分数'
}
},
plotOptions: {
line: {
dataLabels: {
// 开启数据标签
enabled: true
},
// 关闭鼠标跟踪,对应的提示框、点击事件会失效
enableMouseTracking: true
}
},
series: [{
//name: 'alex',
data: data['score']
}]
}); }
})
})
</script>
</body>
</html>

八、 上传作业(os模块)、下载作业(未完成)

九、代码总结

1、目录结构

2、stark.py

# by luffycity.com

from stark.service.stark import site, ModelStark
from django.http import JsonResponse
from .models import * from django.utils.safestring import mark_safe
from django.conf.urls import url from django.shortcuts import HttpResponse, redirect, render site.register(School) class UserConfig(ModelStark):
list_display = ["name", "email", "depart"] site.register(UserInfo, UserConfig) class ClassConfig(ModelStark):
def display_classname(self, obj=None, header=False):
if header:
return "班级名称"
class_name = "%s(%s)" % (obj.course.name, str(obj.semester))
return class_name list_display = [display_classname, "tutor", "teachers"] site.register(ClassList, ClassConfig) class CusotmerConfig(ModelStark):
def display_gender(self, obj=None, header=False):
if header:
return "性别"
return obj.get_gender_display() def display_course(self, obj=None, header=False):
if header:
return "咨询课程"
temp = []
for course in obj.course.all():
s = "<a href='/stark/crm/customer/cancel_course/%s/%s' style='border:1px solid #369;padding:3px 6px'><span>%s</span></a>&nbsp;" % (
obj.pk, course.pk, course.name,)
temp.append(s)
return mark_safe("".join(temp)) # list_display = ["name",'gender','course',"consultant",]
list_display = ["name", display_gender, display_course, "consultant", ] def cancel_course(self, request, customer_id, course_id):
print(customer_id, course_id) obj = Customer.objects.filter(pk=customer_id).first()
obj.course.remove(course_id)
return redirect(self.get_list_url()) def extra_url(self):
temp = []
temp.append(url(r"cancel_course/(\d+)/(\d+)", self.cancel_course))
return temp site.register(Customer, CusotmerConfig)
site.register(Department)
site.register(Course) class ConsultConfig(ModelStark):
list_display = ['customer', 'consultant', 'date', 'note'] site.register(ConsultRecord, ConsultConfig) class CourseRecordConfig(ModelStark):
def score(self, request, course_record_id):
"""录入成绩view"""
study_record_list = StudyRecord.objects.filter(course_record=course_record_id)
print(study_record_list)
score_choices = StudyRecord.score_choices
if request.method == "POST":
print(request.POST) # <QueryDict: 'score_4': ['100'], 'homeword_note_4': ['33']}> data = {} # dic = {1:{'homework_note':'good','score':'90'},2:{'homework_note':'nonono','score':'80'},} for key, value in request.POST.items():
if key == "csrfmiddlewaretoken": continue
field, pk = key.rsplit('_', 1) if pk in data:
data[pk][field] = value
else:
data[pk] = {field: value} print('data', data) for pk, val in data.items():
StudyRecord.objects.filter(pk=pk).update(**val) '''
# 方式1
if field == 'score':
StudyRecord.objects.filter(pk=pk).update(score=value)
else:
StudyRecord.objects.filter(pk=pk).update(homework_note=value.strip())
''' return redirect(request.path) # 跳转到当前url return render(request, 'score.html', locals()) def extra_url(self):
"""录入成绩url"""
temp = []
temp.append(url('record_score/(\d+)', self.score))
return temp def record_score(self, obj=None, header=False):
"""录入成绩a标签"""
if header:
return "录入成绩"
return mark_safe("<a href='record_score/%s'>录入成绩</a>" % (obj.pk)) def record(self, obj=None, header=False):
if header:
return '学习记录'
return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>" % (obj.pk)) list_display = ['class_obj', 'day_num', 'teacher', record, record_score] def patch_studyrecord(self, request, queryset):
print(queryset) # <QuerySet [<CourseRecord: python基础班(9期) day11>]>
temp = []
for course_record in queryset:
student_list = Student.objects.filter(class_list=course_record.class_obj.pk)
for student in student_list:
obj = StudyRecord(student=student, course_record=course_record)
temp.append(obj) StudyRecord.objects.bulk_create(temp) # 批量生成数据 patch_studyrecord.short_description = '批量生成学习记录'
actions = [patch_studyrecord, ] site.register(CourseRecord, CourseRecordConfig) class StudyRecordConfig(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] def patch_late(self, request, queryset):
queryset.update(record='late') patch_late.short_description = '迟到'
actions = [patch_late] site.register(StudyRecord, StudyRecordConfig) class StudentConfig(ModelStark):
def score_view(self, request, stu_id):
"""查看成绩 view"""
if request.is_ajax():
cid = request.GET.get('cid')
sid = request.GET.get('sid') print(cid,sid)
study_record_list = StudyRecord.objects.filter(student=sid,course_record__class_obj=cid) print('study_record_list',study_record_list) # 方案1:构造数据 # [['day11', 85], ['day12', 90]]
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]) print('data_list',data_list) #方案2:构造数据 dic = {day:[day11,day12],score:[85,90]}
dic = {'day':[],'score':[]}
for study_record in study_record_list:
day_num = study_record.course_record.day_num
dic['day'].append('day%s'%day_num)
dic['score'].append(study_record.score)
print(dic)
print(dic['day'])
print(dic['score']) return JsonResponse(dic,safe=False) else:
student = Student.objects.filter(pk=stu_id).first()
class_list = student.class_list.all()
return render(request, 'score_view.html', locals()) def extra_url(self):
"""查看成绩url"""
temp = []
temp.append(url(r"score_view/(\d+)", self.score_view))
return temp def score_show(self, obj=None, header=False):
"""查看成绩 a标签"""
if header:
return "查看成绩"
return mark_safe('<a href="score_view/%s">查看成绩</a>' % (obj.pk)) list_display = ['customer', 'class_list', score_show]
list_display_links = ['customer'] site.register(Student, StudentConfig)

3、stark/service/stark.py

# by luffycity.com
from django.conf.urls import url from django.shortcuts import HttpResponse,render,redirect
from django.urls import reverse
from django.db.models import Q
from django.utils.safestring import mark_safe from stark.utils.page import Pagination
from django.db.models.fields.related import ManyToManyField,ForeignKey class ShowList(object):
def __init__(self,config,data_list,request):
self.config=config
self.data_list=data_list
self.request=request
#分页
data_count=self.data_list.count()
current_page=int(self.request.GET.get("page",1))
base_path=self.request.path self.pagination=Pagination(current_page,data_count,base_path,self.request.GET,per_page_num=10, pager_count=11, )
self.page_data=self.data_list[self.pagination.start:self.pagination.end] # actions
self.actions=self.config.new_actions() # [patch_init,] def get_filter_linktags(self):
print("list_filter:",self.config.list_filter)
link_dic={}
import copy for filter_field in self.config.list_filter: # ["title","publish","authors",]
params = copy.deepcopy(self.request.GET) cid=self.request.GET.get(filter_field,0) print("filter_field",filter_field) # "publish"
filter_field_obj=self.config.model._meta.get_field(filter_field)
print("filter_field_obj",filter_field_obj)
print(type(filter_field_obj))
from django.db.models.fields.related import ForeignKey
from django.db.models.fields.related import ManyToManyField
print("rel======...",filter_field_obj.rel) if isinstance(filter_field_obj,ForeignKey) or isinstance(filter_field_obj,ManyToManyField):
data_list=filter_field_obj.rel.to.objects.all()# 【publish1,publish2...】
else:
data_list=self.config.model.objects.all().values("pk",filter_field)
print("data_list",data_list) temp=[]
# 处理 全部标签
if params.get(filter_field):
del params[filter_field]
temp.append("<a href='?%s'>全部</a>"%params.urlencode())
else:
temp.append("<a class='active' href='#'>全部</a>") # 处理 数据标签
for obj in data_list:
if isinstance(filter_field_obj,ForeignKey) or isinstance(filter_field_obj,ManyToManyField):
pk=obj.pk
text=str(obj)
params[filter_field] = pk
else: # data_list= [{"pk":1,"title":"go"},....]
print("========")
pk=obj.get("pk")
text=obj.get(filter_field)
params[filter_field] =text _url=params.urlencode()
if cid==str(pk) or cid==text:
link_tag="<a class='active' href='?%s'>%s</a>"%(_url,text)
else:
link_tag = "<a href='?%s'>%s</a>" % (_url, text)
temp.append(link_tag) link_dic[filter_field]=temp return link_dic def get_action_list(self):
temp=[]
for action in self.actions:
temp.append({
"name":action.__name__,
"desc":action.short_description
}) # [{"name":""patch_init,"desc":"批量初始化"}] return temp def get_header(self):
# 构建表头
header_list = []
print("header",
self.config.new_list_play()) # [checkbox,"pk","name","age",edit ,deletes] 【checkbox ,"__str__", edit ,deletes】 for field in self.config.new_list_play(): if callable(field):
# header_list.append(field.__name__)
val = field(self.config, header=True)
header_list.append(val) else:
if field == "__str__":
header_list.append(self.config.model._meta.model_name.upper())
else:
# header_list.append(field)
val = self.config.model._meta.get_field(field).verbose_name
header_list.append(val)
return header_list def get_body(self):
# 构建表单数据
new_data_list = []
for obj in self.page_data:
temp = []
for filed in self.config.new_list_play(): # ["__str__",] ["pk","name","age",edit]
if callable(filed):
print("obj-----:",obj)
val = filed(self.config, obj)
else:
try:
field_obj=self.config.model._meta.get_field(filed)
if isinstance(field_obj,ManyToManyField):
ret = getattr(obj,filed).all()
t=[]
for mobj in ret:
t.append(str(mobj))
val=",".join(t)
else:
print("+++++>>",field_obj.choices)
if field_obj.choices:
val = getattr(obj,'get_'+filed+'_display')
else:
val = getattr(obj, filed)
if filed in self.config.list_display_links:
# "app01/userinfo/(\d+)/change"
_url = self.config.get_change_url(obj)
val = mark_safe("<a href='%s'>%s</a>" % (_url, val)) except Exception as e:
val = getattr(obj, filed)
temp.append(val)
new_data_list.append(temp)
return new_data_list '''
[
[1,"alex",12],
[1,"alex",12],
[1,"alex",12],
[1,"alex",12], ] ''' class ModelStark(object): list_display=["__str__",]
list_display_links=[]
modelform_class=None
search_fields=[]
actions = []
list_filter=[] def patch_delete(self, request, queryset): queryset.delete() patch_delete.short_description = "批量删除" def __init__(self,model,site):
self.model=model
self.site=site # 删除 编辑,复选框
def edit(self,obj=None,header=False):
if header:
return "操作"
#return mark_safe("<a href='%s/change'>编辑</a>"%obj.pk)
_url=self.get_change_url(obj) return mark_safe("<a href='%s'>编辑</a>"%_url) def deletes(self,obj=None,header=False):
if header:
return "操作"
# return mark_safe("<a href='%s/change'>编辑</a>"%obj.pk) _url=self.get_delete_url(obj) return mark_safe("<a href='%s'>删除</a>" % _url) def checkbox(self,obj=None,header=False):
if header:
return mark_safe('<input id="choice" type="checkbox">') return mark_safe('<input class="choice_item" type="checkbox" name="selected_pk" value="%s">'%obj.pk) def get_modelform_class(self): if not self.modelform_class:
from django.forms import ModelForm
from django.forms import widgets as wid
class ModelFormDemo(ModelForm):
class Meta:
model = self.model
fields = "__all__"
labels={
""
}
return ModelFormDemo
else:
return self.modelform_class def get_new_form(self,form): for bfield in form:
from django.forms.boundfield import BoundField
print(bfield.field) # 字段对象
print("name",bfield.name) # 字段名(字符串)
print(type(bfield.field)) # 字段类型
from django.forms.models import ModelChoiceField
if isinstance(bfield.field,ModelChoiceField):
bfield.is_pop=True print("=======>",bfield.field.queryset.model) # 一对多或者多对多字段的关联模型表 related_model_name=bfield.field.queryset.model._meta.model_name
related_app_label=bfield.field.queryset.model._meta.app_label _url=reverse("%s_%s_add"%(related_app_label,related_model_name))
bfield.url=_url+"?pop_res_id=id_%s"%bfield.name return form def add_view(self, request):
ModelFormDemo = self.get_modelform_class()
form = ModelFormDemo() form=self.get_new_form(form) if request.method=="POST":
form = ModelFormDemo(request.POST)
if form.is_valid():
obj=form.save() pop_res_id=request.GET.get("pop_res_id") if pop_res_id:
res ={"pk":obj.pk,"text":str(obj),"pop_res_id":pop_res_id}
import json
return render(request, "pop.html", {"res":res}) else:
return redirect(self.get_list_url()) return render(request, "add_view.html", locals()) def delete_view(self, request, id):
url = self.get_list_url()
if request.method=="POST":
self.model.objects.filter(pk=id).delete()
return redirect(url) return render(request, "delete_view.html", locals()) def change_view(self, request, id):
ModelFormDemo = self.get_modelform_class()
print("=====id",id)
edit_obj = self.model.objects.filter(pk=id).first() if request.method=="POST":
form = ModelFormDemo(request.POST,instance=edit_obj)
if form.is_valid():
form.save()
return redirect(self.get_list_url()) return render(request, "add_view.html", locals()) print("***********",edit_obj)
form = ModelFormDemo(instance=edit_obj)
form = self.get_new_form(form) return render(request, "change_view.html", locals()) def new_list_play(self):
temp=[]
temp.append(ModelStark.checkbox)
temp.extend(self.list_display)
if not self.list_display_links:
temp.append(ModelStark.edit)
temp.append(ModelStark.deletes)
return temp def new_actions(self):
temp=[]
temp.append(ModelStark.patch_delete)
temp.extend(self.actions) return temp def get_change_url(self,obj):
model_name = self.model._meta.model_name
app_label = self.model._meta.app_label
print("obj===========",obj)
_url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) return _url def get_delete_url(self, obj):
model_name = self.model._meta.model_name
app_label = self.model._meta.app_label _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk,)) return _url def get_add_url(self): model_name = self.model._meta.model_name
app_label = self.model._meta.app_label _url = reverse("%s_%s_add" % (app_label, model_name)) return _url def get_list_url(self): model_name = self.model._meta.model_name
app_label = self.model._meta.app_label _url = reverse("%s_%s_list" % (app_label, model_name)) return _url def get_serach_conditon(self,request):
key_word = request.GET.get("q","")
self.key_word=key_word search_connection = Q()
if key_word:
# self.search_fields # ["title","price"]
search_connection.connector = "or"
for search_field in self.search_fields:
search_connection.children.append((search_field + "__contains", key_word))
return search_connection def get_filter_condition(self,request):
filter_condition=Q() for filter_field,val in request.GET.items(): # courserecord=2
# if filter_field in self.list_filter:
if filter_field != 'page':
filter_condition.children.append((filter_field,val)) return filter_condition def list_view(self, request):
if request.method=="POST": # action
print("POST:",request.POST)
action=request.POST.get("action") # patch_init
selected_pk=request.POST.getlist("selected_pk")
action_func=getattr(self,action)
queryset=self.model.objects.filter(pk__in=selected_pk)
ret=action_func(request,queryset) #return ret # 获取serach的Q对象
search_connection=self.get_serach_conditon(request) # 获取filter构建Q对象 filter_condition=self.get_filter_condition(request) # 筛选获取当前表所有数据
data_list=self.model.objects.all().filter(search_connection).filter(filter_condition) # 【obj1,obj2,....】 # 按这ShowList展示页面
showlist=ShowList(self,data_list,request) # 构建一个查看URL
add_url=self.get_add_url()
return render(request, "list_view.html", locals()) def extra_url(self): return [] def get_urls_2(self): temp = [] model_name=self.model._meta.model_name
app_label=self.model._meta.app_label temp.append(url(r"^add/", self.add_view,name="%s_%s_add"%(app_label,model_name)))
temp.append(url(r"^(\d+)/delete/", self.delete_view,name="%s_%s_delete"%(app_label,model_name)))
temp.append(url(r"^(\d+)/change/", self.change_view,name="%s_%s_change"%(app_label,model_name)))
temp.append(url(r"^$", self.list_view,name="%s_%s_list"%(app_label,model_name))) temp.extend(self.extra_url()) return temp @property
def urls_2(self):
print(self.model)
return self.get_urls_2(), None, None class StarkSite(object):
def __init__(self):
self._registry={} def register(self,model,stark_class=None):
if not stark_class:
stark_class=ModelStark self._registry[model] = stark_class(model, self) def get_urls(self):
temp=[]
for model,stark_class_obj in self._registry.items():
model_name=model._meta.model_name
app_label=model._meta.app_label
# 分发增删改查
temp.append(url(r"^%s/%s/"%(app_label,model_name),stark_class_obj.urls_2)) '''
url(r"^app01/userinfo/",UserConfig(Userinfo).urls_2),
url(r"^app01/book/",ModelStark(Book).urls_2), '''
return temp @property
def urls(self): return self.get_urls(),None,None site=StarkSite()

4、models.py

from django.db import models

# Create your models here.

class Department(models.Model):
"""
部门表
市场部 1000
销售 1001 """
title = models.CharField(verbose_name='部门名称', max_length=16)
code = models.IntegerField(verbose_name='部门编号', unique=True, null=False) def __str__(self):
return self.title class UserInfo(models.Model):
"""
员工表
""" name = models.CharField(verbose_name='员工姓名', max_length=16)
username = models.CharField(verbose_name='用户名', max_length=32)
password = models.CharField(verbose_name='密码', max_length=64)
email = models.EmailField(verbose_name='邮箱', max_length=64) depart = models.ForeignKey(verbose_name='部门', to="Department", to_field="code", on_delete=True) def __str__(self):
return self.name class Course(models.Model):
"""
课程表
如:
Linux基础
Linux架构师
Python自动化开发精英班
Python自动化开发架构师班
Python基础班
go基础班
"""
name = models.CharField(verbose_name='课程名称', max_length=32) def __str__(self):
return self.name class School(models.Model):
"""
校区表
如:
北京沙河校区
上海校区 """
title = models.CharField(verbose_name='校区名称', max_length=32) def __str__(self):
return self.title class ClassList(models.Model):
"""
班级表
如:
Python全栈 面授班 5期 10000 2017-11-11 2018-5-11
"""
school = models.ForeignKey(verbose_name='校区', to='School', on_delete=True)
course = models.ForeignKey(verbose_name='课程名称', to='Course', on_delete=True) semester = models.IntegerField(verbose_name="班级(期)")
price = models.IntegerField(verbose_name="学费")
start_date = models.DateField(verbose_name="开班日期")
graduate_date = models.DateField(verbose_name="结业日期", null=True, blank=True)
memo = models.CharField(verbose_name='说明', max_length=256, blank=True, null=True, ) # teachers = models.ManyToManyField(verbose_name='任课老师', to='UserInfo',limit_choices_to={'depart_id__in':[1003,1004],})
teachers = models.ManyToManyField(verbose_name='任课老师', to='UserInfo', related_name="abc",
limit_choices_to={"depart__in": [1002, 1005]})
tutor = models.ForeignKey(verbose_name='班主任', to='UserInfo', related_name='classes',
limit_choices_to={"depart": 1001}, on_delete=True) def __str__(self):
return "{0}({1}期)".format(self.course.name, self.semester) class Customer(models.Model):
"""
客户表
"""
qq = models.CharField(verbose_name='qq', max_length=64, unique=True, help_text='QQ号必须唯一') name = models.CharField(verbose_name='学生姓名', max_length=16)
gender_choices = ((1, '男'), (2, '女'))
gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices) education_choices = (
(1, '重点大学'),
(2, '普通本科'),
(3, '独立院校'),
(4, '民办本科'),
(5, '大专'),
(6, '民办专科'),
(7, '高中'),
(8, '其他')
)
education = models.IntegerField(verbose_name='学历', choices=education_choices, blank=True, null=True, )
graduation_school = models.CharField(verbose_name='毕业学校', max_length=64, blank=True, null=True)
major = models.CharField(verbose_name='所学专业', max_length=64, blank=True, null=True) experience_choices = [
(1, '在校生'),
(2, '应届毕业'),
(3, '半年以内'),
(4, '半年至一年'),
(5, '一年至三年'),
(6, '三年至五年'),
(7, '五年以上'),
]
experience = models.IntegerField(verbose_name='工作经验', blank=True, null=True, choices=experience_choices)
work_status_choices = [
(1, '在职'),
(2, '无业')
]
work_status = models.IntegerField(verbose_name="职业状态", choices=work_status_choices, default=1, blank=True,
null=True)
company = models.CharField(verbose_name="目前就职公司", max_length=64, blank=True, null=True)
salary = models.CharField(verbose_name="当前薪资", max_length=64, blank=True, null=True) source_choices = [
(1, "qq群"),
(2, "内部转介绍"),
(3, "官方网站"),
(4, "百度推广"),
(5, "360推广"),
(6, "搜狗推广"),
(7, "腾讯课堂"),
(8, "广点通"),
(9, "高校宣讲"),
(10, "渠道代理"),
(11, "51cto"),
(12, "智汇推"),
(13, "网盟"),
(14, "DSP"),
(15, "SEO"),
(16, "其它"),
]
source = models.SmallIntegerField('客户来源', choices=source_choices, default=1)
referral_from = models.ForeignKey(
'self',
blank=True,
null=True,
verbose_name="转介绍自学员",
help_text="若此客户是转介绍自内部学员,请在此处选择内部学员姓名",
related_name="internal_referral", on_delete=True
)
course = models.ManyToManyField(verbose_name="咨询课程", to="Course") status_choices = [
(1, "已报名"),
(2, "未报名")
]
status = models.IntegerField(
verbose_name="状态",
choices=status_choices,
default=2,
help_text=u"选择客户此时的状态"
) consultant = models.ForeignKey(verbose_name="课程顾问", to='UserInfo', related_name='consultanter',
limit_choices_to={'depart_id': 1001}, on_delete=True) date = models.DateField(verbose_name="咨询日期", auto_now_add=True)
recv_date = models.DateField(verbose_name="当前课程顾问的接单日期", null=True)
last_consult_date = models.DateField(verbose_name="最后跟进日期", ) def __str__(self):
return "姓名:{0},QQ:{1}".format(self.name, self.qq, ) class ConsultRecord(models.Model):
"""
客户跟进记录
"""
customer = models.ForeignKey(verbose_name="所咨询客户", to='Customer', on_delete=True)
consultant = models.ForeignKey(verbose_name="跟踪人", to='UserInfo', on_delete=True)
date = models.DateField(verbose_name="跟进日期", auto_now_add=True)
note = models.TextField(verbose_name="跟进内容...") def __str__(self):
return self.customer.name + ":" + self.consultant.name class Student(models.Model):
"""
学生表(已报名)
"""
customer = models.OneToOneField(verbose_name='客户信息', to='Customer', on_delete=True) username = models.CharField(verbose_name='用户名', max_length=32)
password = models.CharField(verbose_name='密码', max_length=64)
emergency_contract = models.CharField(max_length=32, blank=True, null=True, verbose_name='紧急联系人') class_list = models.ManyToManyField(verbose_name="已报班级", to='ClassList', blank=True)
company = models.CharField(verbose_name='公司', max_length=128, blank=True, null=True)
location = models.CharField(max_length=64, verbose_name='所在区域', blank=True, null=True)
position = models.CharField(verbose_name='岗位', max_length=64, blank=True, null=True)
salary = models.IntegerField(verbose_name='薪资', blank=True, null=True)
welfare = models.CharField(verbose_name='福利', max_length=256, blank=True, null=True)
date = models.DateField(verbose_name='入职时间', help_text='格式yyyy-mm-dd', blank=True, null=True)
memo = models.CharField(verbose_name='备注', max_length=256, blank=True, null=True) def __str__(self):
return self.username class CourseRecord(models.Model):
"""
上课记录表
"""
class_obj = models.ForeignKey(verbose_name="班级", to="ClassList", on_delete=True)
day_num = models.IntegerField(verbose_name="节次", help_text=u"此处填写第几节课或第几天课程...,必须为数字")
teacher = models.ForeignKey(verbose_name="讲师", to='UserInfo', limit_choices_to={"depart_id__in": [1002, 1003]},
on_delete=True)
date = models.DateField(verbose_name="上课日期", auto_now_add=True) course_title = models.CharField(verbose_name='本节课程标题', max_length=64, blank=True, null=True)
course_memo = models.TextField(verbose_name='本节课程内容概要', blank=True, null=True)
has_homework = models.BooleanField(default=True, verbose_name="本节有作业")
homework_title = models.CharField(verbose_name='本节作业标题', max_length=64, blank=True, null=True)
homework_memo = models.TextField(verbose_name='作业描述', max_length=500, blank=True, null=True)
exam = models.TextField(verbose_name='踩分点', max_length=300, blank=True, null=True) def __str__(self):
return "{0} day{1}".format(self.class_obj, self.day_num) class StudyRecord(models.Model):
course_record = models.ForeignKey(verbose_name="第几天课程", to="CourseRecord", on_delete=True)
student = models.ForeignKey(verbose_name="学员", to='Student', on_delete=True)
record_choices = (('checked', "已签到"),
('vacate', "请假"),
('late', "迟到"),
('noshow', "缺勤"),
('leave_early', "早退"),
)
record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)
score_choices = ((100, 'A+'),
(90, 'A'),
(85, 'B+'),
(80, 'B'),
(70, 'B-'),
(60, 'C+'),
(50, 'C'),
(40, 'C-'),
(0, ' D'),
(-1, 'N/A'),
(-100, 'COPY'),
(-1000, 'FAIL'),
)
score = models.IntegerField("本节成绩", choices=score_choices, default=-1)
homework_note = models.CharField(verbose_name='作业评语', max_length=255, blank=True, null=True)
note = models.CharField(verbose_name="备注", max_length=255, blank=True, null=True) homework = models.FileField(verbose_name='作业文件', blank=True, null=True, default=None)
stu_memo = models.TextField(verbose_name='学员备注', blank=True, null=True)
date = models.DateTimeField(verbose_name='提交作业日期', auto_now_add=True) def __str__(self):
return "{0}-{1}".format(self.course_record, self.student)

5、stark/apps中  启动stark组件

6、settings设置templates路径,static路径

2 CRM 讲师与学生,highcharts应用的更多相关文章

  1. CRM - 讲师与学生

    一.讲师与学生简介 1.初始化 course_record, study_record.2.学习记录3.录入成绩4.显示成绩 ajax 查询 柱状图展示成绩 highcharts 5.上传作业(os模 ...

  2. CRM——讲师与学生

    一.课程记录和学习记录 1.初始化 course_record, study_record.2.学习记录3.录入成绩4.显示成绩 ajax 查询 柱状图展示成绩 highcharts 5.上传作业(o ...

  3. Django项目:CRM(客户关系管理系统)--79--69PerfectCRM实现CRM业务流程(bpm)学生讲师分页

    # student_views.py # ————————60PerfectCRM实现CRM学生上课记录———————— from django.shortcuts import render #页面 ...

  4. Django项目:CRM(客户关系管理系统)--73--63PerfectCRM实现CRM讲师下载作业

    # teacher_urls.py # ————————62PerfectCRM实现CRM讲师讲课记录———————— from django.conf.urls import url from bp ...

  5. Django项目:CRM(客户关系管理系统)--72--62PerfectCRM实现CRM讲师讲课记录

    #urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...

  6. Django - 学习目录

    Django 基础 web应用/http协议/web框架 Django简介 Django - 路由层(URLconf) Django - 视图层 Django - 模板层 Django - 模型层 - ...

  7. python全栈开发之路

    一.Python基础 python简介 python数据类型(数字\字符串\列表) python数据类型(元组\字典) python数据类型(集合) python占位符%s,%d,%r,%f prin ...

  8. CRM系统(第二部分)

      阅读目录 一.讲师与学生简介 二. 初始化 ,studyrecord, 三.初始化 course_record:批量生成学习记录 四. 考勤  url跳转 五.录入成绩 六.highcharts表 ...

  9. 7.1 - CRM系统

    一.简介 crm 客户关系管理软件 ( Customer Relationship Management ) ( 详细内容 ) stark组件(仿admin组件)( 详细内容 ) rbac组件(基于角 ...

随机推荐

  1. [转] iOS文字排版(CoreText)那些事儿

    文章转载自 http://www.cocoachina.com/applenews/devnews/2014/0521/8504.html iOS文字排版(CoreText)那些事儿 转自阿毛的蛋疼地 ...

  2. Tomcat 配置学习

    1 server.xml <host appBase="d:/aaa"> <Context path="/smswap" reloadable ...

  3. September 23rd 2017 Week 38th Saturday

    Lonely people will always remember his life occurred in each person. 寂寞的人总是会用心记住他生命中出现过的每个人. If you ...

  4. November 20th 2016 Week 47th Sunday

    Learn from yesterday, live for today, look to tomorrow. 学习昨天,活在今天,展望明天. There is always room at the ...

  5. 关于print缩不缩进%有else没else的影响

    关于print缩不缩进%有else没else的影响 if gender == "男": # = 赋值. == 判断print("上厕所")else: print ...

  6. 整体修改VS中C++工程和解决方案命名问题

    目标:将所有basestation相关的修改为PPPStream 首先,复制一份用于修改的解决方案文件夹,然后打开解决方案,如下图,左侧的两个basestation都重新命名为PPPStream. 第 ...

  7. 笔记本无密码连接wifi

    用手机可以用wifi万能钥匙破解wifi,就想找电脑版的wifi万能钥匙,然并卵. 就去寻找各种办法,最后找了个巧, 用手机下载wifi万能钥匙连接,并且使用数据线连接上笔记本. 然后手机设置中找到开 ...

  8. 在.NET中操作数字证书(新手教程)

    .NET为我们提供了操作数字证书的两个主要的类,分为为: System.Security.Cryptography.X509Certificates.X509Certificate2类, 每个这个类的 ...

  9. Spring中手动增加配置文件中占位符引用的变量

    在项目中遇到一个这样的需求,项目的配置文件由外部传入,这时spring配置文件那些占位符变量该如何取值呢? 解决这个问题的做法有几种,我想到的大概有以下三种: 1.通过系统属性来实现,把外部传入的配置 ...

  10. isa class superclass metaclass

    http://www.cnblogs.com/feng9exe/p/7232915.html Note: 其实这里的难点就在于对 和 的区分. .class 当 target 是 Instance 则 ...