crm作业知识点集合[三]
知识点1
我们要实现一个这样的功能,在学生表中,可以查看每个学生的报名的班级的所有的成绩,就是下图的效果
1、首先我们需要在学生表中自定义一列,这一列的内容就是一个a标签,指向另外一个页面,而我们在另外一个页面显示显示这个学生的所有的成绩
新添加一列的函数如下
def score_show_url(self,obj=None,header=False):
if header:
return "查看成绩"
else: temp = "<a href='/stark/crm/student/{sid}/'>查看个人成绩</a>".format(sid=obj.id)
return mark_safe(temp)
2、由于我们这里新增了一个url,所以需要为这个url设计一个新的视图函数
首先为这个url设计对应的视图函数的名称
def extra_url(self):
temp = []
temp_url = url(r'(?P<sid>\d+)/',self.show_score)
temp.append(temp_url) return temp
然后我们设计具体的视图函数,这个视图函数是完整的视图函数,我们先不用管,只需要知道这个流程就可以了
def show_score(self,request,sid): stu_obj = models.Student.objects.get(id=sid)
# 拿到学生对象 stu_class_list = stu_obj.class_list.all()
if request.is_ajax(): sid = request.GET.get("sid")
cid = request.GET.get("cid")
# 拿到这个学生的所报的班级的queryset对象 stu_record_dict = {}
for record in stu_class_list:
stu_record_dict[record.id] = record.courserecord_set.all() data_list = []
for k,v in stu_record_dict.items():
# print(k,cid,type(k),type(cid))
if k == int(cid):
for m in v:
print(stu_obj,m,m.studyrecord_set.filter(student = stu_obj)[0].get_score_display())
temp = [str(m),m.studyrecord_set.filter(student = stu_obj)[0].score]
data_list.append(temp)
import json
print(data_list)
from django.http import JsonResponse
return JsonResponse(data_list,safe=False) return render(request,"score_view.html",locals())
3、首先这个视图函数接收一个参数,这个参数就是学生的id,我们通过拿到这个学生的id就可以获取这个学生的所有的成绩了
4、然后返回一个页面
5、然后我们在下这个页面的html代码
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
</head>
<body>
<h3>查看<b>{{ stu_obj.username }}</b>成绩</h3> <div class="container">
<div class="row">
<div class="col-md-9">
<form 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 stu_class_list %}
<tr>
<td>{{ cls }}</td>
<td>{{ cls.tutor }}</td>
<td>{% for t in cls.teachers.all %}
{% if forloop.last %}
{{t.name}}
{% else %}
{{ t.name }} &
{% endif %}
{% endfor %}
</td>
<td><a class="view_score" cid={{ cls.id }} href="#">查看成绩</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
</div> </div>
</div>
</body>
下面我们分解一下html的代码,其实就是一个table标签,表头的代码
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>班级</th>
<th>班主任</th>
<th>任课老师</th>
<th>查看成绩</th>
</tr>
</thead>
表身体的代码
<tbody>
{% for cls in stu_class_list %}
<tr>
<td>{{ cls }}</td>
<td>{{ cls.tutor }}</td>
<td>{% for t in cls.teachers.all %}
{% if forloop.last %}
{{t.name}}
{% else %}
{{ t.name }} &
{% endif %}
{% endfor %}
</td>
<td><a class="view_score" cid={{ cls.id }} href="#">查看成绩</a></td>
</tr>
{% endfor %}
</tbody>
这里注意一下,判断是否为for循环的最后一个
最后我们看下前端页面的效果
首先是在学生表中新增了一列数据
然后我们点击任意一个a标签,进入这个用户的查看成绩的页面
重点是这里,查看成绩的这个a标签
我们要为这个a标签绑定一个单击的事件,点击这个a标签,发送一个ajax的事件
首先我们看下ajax发送给后端的数据是什么,将学生的id和班级的id发送过去了,因为一个学生可以 报多个班级,我们是这里为每个学生的每个班级设计了a标签的按钮
$.ajax(
{
url: "",
data: {
sid: "{{ stu_obj.id }}",
cid: $(this).attr("cid"),
},
type: "get",
然后我们在看下视图函数,如何通过班级的id和学生的id拿到所要的成绩信息
if request.is_ajax(): sid = request.GET.get("sid")
cid = request.GET.get("cid")
# 拿到这个学生的所报的班级的queryset对象 stu_record_dict = {}
for record in stu_class_list:
stu_record_dict[record.id] = record.courserecord_set.all() data_list = []
for k,v in stu_record_dict.items():
# print(k,cid,type(k),type(cid))
if k == int(cid):
for m in v:
print(stu_obj,m,m.studyrecord_set.filter(student = stu_obj)[0].get_score_display())
temp = [str(m),m.studyrecord_set.filter(student = stu_obj)[0].score]
data_list.append(temp)
import json
print(data_list)
from django.http import JsonResponse
return JsonResponse(data_list,safe=False)
首先这里有一个新的知识点,就是判断这次的请求是否为ajax的请求
这里我们点击查看成绩的按钮,我们用了一个highcharts的组件,这个组件就要接受一个列表套列表的数据结构,上面我们就组件了一个这样的结构
然后引入highcharts的组件的js文件
<script src="/static/jq/jquery-3.3.1.js"></script>
<script src="/static/highcharts/code/highcharts.js"></script>
下面这段代码是highcharts中的代码,我们只需要按照他的要求把数据传递过来就可以了
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:.1f} 百万</b>'
},
series: [{
name: '总人口',
{# data: [#}
{# ['上海', 24.25],#}
{# ['卡拉奇', 23.50],#}
{##}
{# ],#}
data: data,
dataLabels: {
enabled: true,
rotation: -90,
color: '#FFFFFF',
align: 'right',
format: '{point.y:.1f}', // :.1f 为保留 1 位小数
y: 10
}
}]
});
}
}
)
})
页面的的效果如下
知识点2
实现一个这样的功能,我们会新增一个页面,这个页面就是查看公共单的页面,什么叫做公共单,我们这里是这样定义的
a、这个客户未报名
b、销售跟进这个客户10天,还未成单
c、销售连续三天未跟进该客户
首先我们需要在客户表中新增一个url
def extra_url(self):
temp = []
temp_url = url(r'delcourse/(?P<customid>\d+)/(?P<courseid>\d+)',self.del_course)
temp_url = url(r'pub', self.pub)
temp.append(temp_url) return temp
这个就是我们新定义的url
然后在写pub这个视图函数
def pub(self,request):
# 1、过滤未报名的学生
# 2、过滤三天未跟进的学生
# 3、过滤10天未成单的学生 from django.db.models import Q
import datetime
time_delta3 = datetime.timedelta(days=3)
time_delta10 = datetime.timedelta(days=10)
q_obj = Q()
q_obj.connector = "OR"
q_obj.children.append(("last_consult_date__lt",datetime.datetime.now() - time_delta3))
q_obj.children.append(("recv_date__lt",datetime.datetime.now() - time_delta10)) pub_obj_list = models.Customer.objects.filter(q_obj,status=2) return render(request,"pub.html",locals())
这里我们用到了Q对象,这里要非常注意,Q对象的children.append方法要传递一个tuple进去
这里,还有一个知识点就是,我们定义时间对象,超出几天几年,用下面的方法来实现,datetime.timedelta这个方法,下面的例子就是判断当前时间减去三天的时间对象,和当前时间减去10天的时间对象
如果过滤的时候,Q对象和字段过滤一起使用,则字段对象必须放在最后
下面我们看下html的代码
html的代码就很简单了
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
</head>
<body>
<h3>查看客户</h3> <div class="container">
<div class="row">
<div class="col-md-9">
<form method="post">
{% csrf_token %}
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>qq</th>
<th>性别</th>
<th>当前的课程顾问</th>
<th>查看跟进记录</th>
<th>确认跟进</th>
</tr>
</thead>
<tbody>
{% for cus in pub_obj_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ cus.name }}</td>
<td>{{ cus.qq }}</td>
<td>{{ cus.gender }}</td>
<td>{{ cus.consultant }}</td>
<td><a href="/stark/crm/consultrecord/?customer={{ cus.id }}">查看跟进记录</a></td>
<td><a href="#">确认跟进</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
</div> </div>
</div>
</body>
主要是看下这里,forloop.counter
还有就是a标签
然后我们看下前端的效果,pub这个url对应的前端的页面
点击一下查看跟进记录这个a标签的效果
这里我们看下跟进的函数是怎么写的
先添加一个跟进的url
def extra_url(self):
temp = []
temp_url = url(r'delcourse/(?P<customid>\d+)/(?P<courseid>\d+)',self.del_course)
temp.append(temp_url)
temp_url = url(r'pub/', self.pub)
temp.append(temp_url)
temp_url = url(r'further/(?P<cid>\d+)/', self.further)
temp.append(temp_url)
temp_url = url(r'mycustomer/', self.mycustomer)
temp.append(temp_url) return temp
然后我们在写url对应的视图函数
def further(self,request,cid):
import datetime
userinfo_id = 8
userinfo_obj = models.UserInfo.objects.get(id=userinfo_id)
further_status = models.CustomerDistrbute.objects.filter(id=cid)[0].status
if further_status == 1:
return HttpResponse("已经被跟进")
else:
now_date = datetime.datetime.now()
models.Customer.objects.filter(id=cid).update(
consultant = userinfo_obj,
recv_date = now_date,
last_consult_date = now_date
) models.CustomerDistrbute.objects.create(
customer_id = cid,
consultant = userinfo_obj,
date = now_date,
status = 1
) return HttpResponse("跟进成功")
这里有一个逻辑就是为了防止2个人同时点击跟进导致的问题
crm作业知识点集合[三]的更多相关文章
- crm作业知识点集合[二]
知识点1 前面我们实现了这个功能,就是在models中如果有了choice选项,我们可以实现在页面显示这个chocice的value值,而不是key值,我们这个知识点就是在优化一下这个点 首先如果表中 ...
- crm作业知识点集合[一]
知识点1 1.当我们通过model建立一对多或者多对多的关系的时候,默认情况下,会关联所有的字段,如果我们使用djanog的forms的话,可以加一个属性,限制我这个字段只关联哪些字段,就是用下面的写 ...
- C#基础第三天-作业答案-集合-冒泡排序-模拟名片
.冒泡排序 Console.WriteLine("对集合里的数进行排序,请输入第一个数:"); int a = int.Parse(Console.ReadLine()); Con ...
- fullcalendar日历控件知识点集合
1.基本的语法: 首先,fullcalendar和JQUERY一样,以面向对象的方式来组织代码.当然,这里的面向对象不过指能够把整个fullcalendar理解为一个类,这个类里包含有非常多的属性.方 ...
- Java 面试知识点解析(三)——JVM篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
- CSS知识点(三)
十三.标准文档流. 标准文档流下有哪些微观现象? 1.空白折叠现象 多个空格会被合并成一个空格显示到浏览器页面中.img标签换行写.会发现每张图片之间有间隙,如果在一行内写img标签,就解决了这个问题 ...
- Hibernate知识点小结(三)-->一对多与多对多配置
一.多表关系与多表设计 1.多表关系 一对一: 表的设计原则(分表原则): 优化表的性能 基于语意化分表 ...
- 这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)
在前2篇文章这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧 和这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,大伙热情高涨.再次拿出自己的私货,在.NET平台 ...
- php知识点集合
--------------------------------------------------------- PHP知识大全 ------------------------ ...
随机推荐
- Spring boot 注册Filter , Listener, Servlet
1: ServletRegistrationBean Servlet @Bean public ServletRegistrationBean myServlet(){ ServletRegist ...
- 调用DATASNAP+FIREDAC的远程方法有时会执行二次SQL或存储过程的BUG(转永喃兄)
调用DATASNAP+FIREDAC的远程方法有时会执行二次SQL或存储过程的BUG 1)查询会重复执行的情形:Result := DATASETPROVIDER.Data会触发它关联的DATASET ...
- Linux文件的时间
关于Linux文件的ctime.atime和mtime等几个时间的介绍,推荐<Linux的3个文件时间>比较不错,这篇文章已经介绍的比较全面了,但是本文对它做进一步的解释,并对一些情况进行 ...
- Unit 1 overview of IT Industry
Unit 1 overview of IT IndustryConcept LearningIT Industry OutlookThe term technology commonly refers ...
- DNS协议工作过程;DNS的安全隐患
DNS协议工作过程 下面以域名为m.xyz.com的主机欲通过另一个主机的域名y.abc.com的IP地址为例,简述DNS协议过程. 主机m.xyz.com先向其本地服务器dns.xyz.com进 ...
- ajaxfileupload.js上传文件兼容IE7及以上版本
要兼容IE789,要修改ajaxfileupload.js;要将此处的代码替换掉 if(window.ActiveXObject) { var io = document.createElement( ...
- JAVA面试中的陷阱
第一,谈谈final, finally, finalize的区别.最常被问到. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以impl ...
- 解决运行wamp提示“MSVCR110.dll”丢失的问题!
我在Windows系统上安装wampserver2.5 64位,安装到最后,总是提示丢失msvcr110.dll 解决办法: 到这个网站下载一个Visual C++ Redistributable f ...
- eval解析字符串为JSON对象
对于服务器返回的JSON字符串,如果jquery异步请求没做类型说明,或者以字符串方式接受,那么需要做一次对象化处理,方式不是太麻烦,就是将该字符串放于eval()中执行一次. 这种方式也适合以普通j ...
- spring 中AOP的基本知识点
首先AOP就是一个动态代理,主要运用在事务控制,日志记录,安全控制等方面 1.连接点(Joinpoint):一个连接点 总是 代表一个方法的执行. 2.切入点(Pointcut):匹配连接点的 表达式 ...