第10节、案例-客户关系管理系统之增删改查笔记
第10节、案例-客户关系管理系统之增删改查笔记
一、建立模型
1、导入模型
fromdjango.dbimportmodels
2、创建学生表
classStudent(models.Model):# 学生表
name=models.CharField(max_length=20)
age=models.SmallIntegerField()
sex=models.SmallIntegerField(default=1)
qq=models.CharField(max_length=20,unique=True)
phone=models.CharField(max_length=20,unique=True)
c_time=models.DateTimeField(verbose_name='创建时间',auto_now_add=True)
e_time=models.DateTimeField(verbose_name='修改时间',auto_now=True)
grade=models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True)
is_delete=models.BooleanField(default=False)# 一般实际开发过程中,我们不会直接删除数据,而是给数据加上is_delete字段,来标记数据的状态。
def__str__(self):
return'%s-%s-%s'%(self.name,self.age,self.sex)
3、创建学生详情表
classStudentDetail(models.Model):#学生详情表
num=models.CharField('身份证',max_length=40,unique=True)
college=models.CharField('毕业学校',max_length=20,default='')
student=models.OneToOneField('Student',on_delete=models.CASCADE,related_name='detail')
def__str__(self):
return'%s-%s'%(self.num,self.college)
4、创建班级表
classGrade(models.Model):# 班级表
name=models.CharField('班级名称',max_length=20)
num=models.CharField('班期',max_length=20)
def__str__(self):
return'%s-%s'%(self.name,self.num)
5、创建课程表
classCourse(models.Model):# 课程表
name=models.CharField('课程名称',max_length=20)
student=models.ManyToManyField('Student',through='Enroll')
def__str__(self):
return'%s'%self.name
6、创建学生表与课程表的中间表
classEnroll(models.Model):# 课程与学生多对多中间表
student=models.ForeignKey('Student',on_delete=models.CASCADE)
course=models.ForeignKey('Course',on_delete=models.CASCADE)
pay=models.FloatField('缴费金额',default=0)
c_time=models.DateTimeField(verbose_name='创建时间',auto_now_add=True)
def__str__(self):
return'%s'%self.pay
##
二、增删改查功能实现
1、index页面视图函数
fromdjango.shortcutsimportrender,redirect,reverse
fromdjango.httpimportHttpResponse
fromstudent.modelsimportStudent,Grade,StudentDetail
fromdjango.db.modelsimportQ
fromdjango.core.paginatorimportPaginator
# Create your views here.
defindex(request):
section='学生列表'
search=request.POST.get('search','').strip()# 接收从html的form表单传过来的参数
ifsearch:
ifsearch.isdigit():# 如果是数值类型则
sts=Student.objects.filter(Q(qq=search)|Q(phone=search),is_delete=False)# 用qq和phone去匹配
else:# 如果是字符型
sts=Student.objects.filter(name=search,is_delete=False)# 则和名字匹配
else:# search都没有匹配到则查询所有学生
sts=Student.objects.filter(is_delete=False)
sts=sts.order_by('-c_time')# 排序
returnrender(request,'student/index.html',context={
'sts':sts,
'section':section,
'search':search,
})
2、学生删除页视图
defstudent_delete(request,pk):
student=Student.objects.get(pk=pk)# 查询id为pk的学生
student.is_delete=True# 将is_delete标记为True,
student.save()# 保存
returnredirect(reverse('student:index'))
3、学生详情页视图
defstudent_detail(request,pk):
section='学生详情'
grades=Grade.objects.all()# 查询所有班级
sts=Student.objects.get(pk=pk)# 获取当前id为pk的学生信息
grade=Grade.objects.get(pk=sts.grade_id)# 查询指定学生的班级
detail=StudentDetail.objects.get(student=sts)# 查询指定学生的详情
returnrender(request,'student/student_detail.html',context={
'section':section,
'grades':grades,
'sts':sts,
'grade':grade,
'detail':detail,
})
4、添加页视图函数
defstudent_add(request):
section='添加学生信息'
grades=Grade.objects.all()# 获取所有的班级
ifrequest.method=='GET':
returnrender(request,'student/student_detail.html',context={
'section':section,
'grades':grades,
})
ifrequest.method=='POST':
# 获取班级信息
grade_id=request.POST.get('grade')# 获取前端传回来的grade.id
try:
grade=Grade.objects.get(pk=grade_id)
except:
grade=None
# 获取学生信息姓名、年龄、性别、qq、电话
data= {
'name':request.POST.get('name'),
'age':request.POST.get('age'),
'sex':request.POST.get('sex'),
'qq':request.POST.get('qq'),
'phone':request.POST.get('phone'),
'grade':grade#表关联,在student中
}
student=Student.objects.create(**data)
# 获取学生详情信息
StudentDetail.objects.create(
num=request.POST.get('num'),
college=request.POST.get('college'),
student=student# 表关联
)
returnredirect(reverse('student:index'))
5、修改学生信息页视图函数
defstudent_edit(request,pk):
section='修改学生信息'
sts=Student.objects.get(pk=pk)# 查询id为pk的学生
grade=Grade.objects.get(pk=sts.grade_id)# 查询指定学生的班级
detail=StudentDetail.objects.get(student=sts)# 查询指定学生的详情
ifrequest.method=='GET':
returnrender(request,'student/student_detail.html',context={
'section':section,
'sts':sts,
'grade':grade,
'detail':detail,
})
ifrequest.method=='POST':
# 获取班级信息
grade_id=request.POST.get('grade')# 获取前端传回来的grade
try:
grade=Grade.objects.get(pk=grade_id)# 获取学生的班级
except:
grade=None
# 获取学生信息并修改
student=Student.objects.get(pk=pk)
student.name=request.POST.get('name')
student.age=request.POST.get('age')
student.sex=request.POST.get('sex')
student.qq=request.POST.get('qq')
student.phone=request.POST.get('phone')
student.grade=grade# 表关联
# 获取学生详情
try:
detail=student.detail# 表关联,关联表在student
except:
detail=StudentDetail()
detail.student=student# 表关联,关联表在detail
detail.num=request.POST.get('num')
detail.college=request.POST.get('college')
detail.save()# 保存
student.save()# 保存
returnredirect(reverse('student:index'))
三、分页功能实现
1、对主页分页方法一
1.1主页的视图函数
defindex(request):
section='学生列表'
search=request.POST.get('search','').strip()# 接收从html的form表单传过来的参数
ifsearch:
ifsearch.isdigit():# 如果是数值类型则
sts=Student.objects.filter(Q(qq=search)|Q(phone=search),is_delete=False)# 用qq和phone去匹配
else:# 如果是字符型
sts=Student.objects.filter(name=search,is_delete=False)# 则和名字匹配
else:# search都没有匹配到则查询所有学生
sts=Student.objects.filter(is_delete=False)
sts=sts.order_by('-c_time')# 排序
# 分页
total_num=sts.count()# 总的数据量
per_page=int(request.GET.get('per_page',5))# 每页默认条数为5
page=int(request.GET.get('page',1))# 当前页面默认为第1页
p=Paginator(sts,per_page,allow_empty_first_page=True)
sts=p.get_page(page)# 每页显示的数据
total_page=p.num_pages# 总的页面数
page_list=p.page_range# 获取页面范围
returnrender(request,'student/index.html',context={
'sts':sts,
'section':section,
'search':search,
'total_num':total_num,
'total_page':total_page,
'page':page,
'per_page':per_page,
'page_list':page_list,
})
1.2、html中页码的设置
navaria-label="Page navigation"style="display: inline-block"
ulclass="pagination"
li{%ifpage==1%}class="disabled"{%endif%}
ahref="{% if page 1 %}{% url 'student:index' %}?page={{ page|add:-1 }}per_page={{ per_page }}{% else %}{% url 'student:index' %}?page={{ page }}per_page={{ per_page }}{% endif %}"aria-label="Previous"
spanaria-hidden="true"上一页/span
/a
/li
{% for i in page_list %}
li{%ifpage==i%}class="active"{%endif%}ahref="{{ request.path }}?page={{ i }}per_page={{ per_page }}"{{ i }}/a/li
{% endfor %}
li{%ifpage==total_page%}class="disabled"{%endif%}
ahref="{% if page total_page %}{% url 'student:index' %}?page={{ page|add:1 }}per_page={{ per_page }}{% else %}{% url 'student:index' %}?page={{ page }}per_page={{ per_page }}{% endif %}"aria-label="Next"
spanaria-hidden="true"下一页/span
/a
/li
/ul
/nav
!-- Single button --
divclass="btn-group"style="display: inline-block; margin-top: -68px"
buttontype="button"class="btn btn-default dropdown-toggle"data-toggle="dropdown"aria-haspopup="true"aria-expanded="false"
{{ per_page }}条/页spanclass="caret"/span
/button
ulclass="dropdown-menu"
liahref="{% url 'student:index' %}?page={{ page}}per_page= 5 "5条/页/a/li
liahref="{% url 'student:index' %}?page={{ page}}per_page= 10 "10条/页/a/li
liahref="{% url 'student:index' %}?page={{ page}}per_page= 15 "15条/页/a/li
liahref="{% url 'student:index' %}?page={{ page}}per_page= 20 "20条/页/a/li
/ul
/div
2、对主页分页方法二(利用包含标签)
2.1、index中的视图函数
defindex(request):
section='学生列表'
search=request.POST.get('search','').strip()# 接收从html的form表单传过来的参数
ifsearch:
ifsearch.isdigit():# 如果是数值类型则
sts=Student.objects.filter(Q(qq=search)|Q(phone=search),is_delete=False)# 用qq和phone去匹配
else:# 如果是字符型
sts=Student.objects.filter(name=search,is_delete=False)# 则和名字匹配
else:# search都没有匹配到则查询所有学生
sts=Student.objects.filter(is_delete=False)
sts=sts.order_by('-c_time')# 排序
# 分页
total_num=sts.count()# 总的数据量
per_page=int(request.GET.get('per_page',5))# 每页默认条数为5
page=int(request.GET.get('page',1))# 当前页面默认为第1页
p=Paginator(sts,per_page,allow_empty_first_page=True)
sts=p.get_page(page)# 每页显示的数据
total_page=p.num_pages# 总的页面数
page_list=p.page_range# 获取页面范围
returnrender(request,'student/index.html',context={
'sts':sts,
'section':section,
'search':search,
'total_num':total_num,
'total_page':total_page,
'page':page,
'per_page':per_page,
'page_list':page_list,
})
2.2、在templatetags文件夹中创建student_custormer_tags.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# author:cyb time:2019/5/25 23:34
fromdjangoimporttemplate
register=template.Library()
@register.inclusion_tag('student/paginitor.html',takes_context=True)
defpagination_html(context):# 谁引用就导入谁的context
total_page=context['total_page']# 总的页面数
page=context['page']# 显示第几页的数据
page_list=context['page_list']# 页面范围
per_page=context['per_page']# 每页条数
'''
假设现在total_page = 6
两种页码控制方法:
当num = 1 # 当前页面左右各有几页
上一页 1 2 3 下一页
上一页 4 5 6 下一页
上一页 1 2 下一页
上一页 5 6 下一页
当num = 2 # 当前页面左右各有几页
上一页 1 2 3 下一页
上一页 1 2 3 4 下一页
上一页 1 2 3 4 5 下一页
上一页 2 3 4 5 6 下一页
上一页 4 5 6 下一页
'''
page_list= []
num=2
# 1、左边 + 当前页显示的页码列表
# 1.1、左边不够显示时,页码范围1到当前页
ifpage-num=0:
foriinrange(1,page+1):
page_list.append(i)
else:# 左边够显示时,页码范围page-num到当前页
foriinrange(page-num,page+1):
page_list.append(i)
# 2、右边 + 当前页显示的页码列表
# 2.1、右边不够显示时,页码范围当前页到total_page
ifpage+num=total_page:
foriinrange(page+1,total_page+1):
page_list.append(i)
# 2.2、右边够显示时,页码范围(当前页+1)到(当前页+num)
else:
foriinrange(page+1,page+num):
page_list.append(i)
return{
'total_page':total_page,
'page':page,
'page_list':page_list,
'per_page':per_page
}
2.3、在app中新建一个包含标签渲染模板paginitor.html
ulclass="pagination"
li{%ifpage==1%}class="disabled"{%endif%}
a{%ifpage1 %} href="{% url 'student:index' %}?page={{ page|add:'-1' }}per_page={{ per_page }}{% endif %}" aria-label="Previous"
spanaria-hidden="true"«/span
/a
/li
{% for page_num in page_list %}
li{%ifpage_num==page%}class="active"{%endif%}ahref="{{ request.path }}?page={{ page_num }}per_page={{ per_page }}"{{ page_num }}/a/li
{% endfor %}
li{%ifpage==total_page%}class="disabled"{%endif%}
a{%ifpage total_page %} href="{{ request.path }}?page={{ page|add:'1' }}per_page={{ per_page }}{% endif %}" aria-label="Next"
spanaria-hidden="true"»/span
/a
/li
/ul
2.4、在index.html中导入后在对应位置引用
1、导入:{% load student_customer_tags %}
2、引用:
nav aria-label="Page navigation" style="display: inline-block"
{% pagination_html %}
/nav
四、页面展示
1、主页展示
2、添加页展示
3、修改页展示
企业如何减少客户流失率
客户的流失是在所难免的,但是如果客户流失率过高,那就直接影响到企业的盈利,甚至会成为企业走向倒闭的一个先兆。如何避免客户过度流失呢?那就要从产品、服务及客户管理着手。
企业经营中,产品是硬道理,服务是软道理,客户管理才是可以左右的关键。那么,如何管理好客户呢?这就不得不提CRM系统了。
CRM系统是一款以客户为核心的管理软件,一款好的CRM系统不仅可以帮助企业拓宽获客渠道,还能提高老客户留存率,提升企业的市场份额及利润,增强企业竞争力。
C2P功能云的CRM模块就是一款很实用的客户管理系统,它支持单独购买,也可以搭配其他模块一起购买,能帮助企业多渠道自动获客,全过程跟进签单,真正做到以客户为中心。还可以协助管理销售,科学分配商机、线索,帮助销售员分析成交率,通过工业云CRM系统,公司能有效地将所有商机线索、准客户、销售跟踪过程、已签约客户、丢失客户等整个客户的生态链给管理起来。
企业微信scrm系统开发哪个好?
适合企业微信管理客户的,基本上就这么几类:
1、用微信群运营客户的企业,推荐用企业微信群替代,因为企业微信适合规模化社群运营,自带进群欢迎、自动回复、自动踢人、数据分析、支持社群裂变;
2、大企业、大品牌,推荐企业微信,因为企业微信实名认证、强品牌背书;
3、教育、零售、餐饮、金融、保险、家居、大健康、车企、房企、to B 销售,推荐企业微信,都已经跑出成熟方案和案例,客户集中管理,不担心销售离职了带走;
4、抖音、百度、朋友圈、信息流广告投放获客需求的,推荐企业微信,传统的 CRM 只是基于手机线索的流转,而基于企业微信的 SCRM,可以带 S 属性,能打通微信聊天记录、打通与客户的微信互动记录,你发的资料和朋友圈有没有读取都能知道。补充了 S 端数据,你的客户画像,也不再是表格里的一个个字段,而是微信好友的一个个标签、一个个属性,可以针对性的 标签精细群发、还能做精细的 SOP 推送,营销自动化。
企业微信客户管理系统哪个好?具体取决于需求,看几个方面:
1、基础 CRM 功能是否完备
2、是否充分结合企业微信特性
3、是否支持与内部系统打通
4、除了工具外,服务是否足够好。
用过一个比较不错的SCRM服务商,微友助手SCRM,他们家的早期业务是围绕微信生态展开的,是专业的微信群机器人管理专家。拥有群数据分析,新加好友自动应答,自动拉人入群,自动加群用户为好友,入群欢迎语,机器人聊天,消息定时群发,机器人自动回复,群签到,微信群文件、群成员管理等数十项强大功能。
近两年也着重做企业微信SCRM,他们有着丰富的个微客户资源,所以对不同行业的用户需求有着很深刻的理解,而且在做产品功能的时候会结合很多场景化的东西去思考,对企业使用个微转型使用企微也有着他们自己的一些可复用经验。
零售客户关系管理系统中征信查询申请功能中的查询形式有以下几种
1、首先是直接携带本人有效身份证件到中国人民银行网点柜台查询。
2、其次是携带本人有效身份证件到中国人民银行分支行,通过网点的征信报告自助查询机查询。
3、最后是通过网络查询,网络查询个人征信的唯一正规渠道为“中国人民银行征信中心”,用户可以通过中国人民银行征信中心官方网站,进入到互联网个人信用信息查询平台,然后按照系统提升进行查询操作。
中国移动协作型客户关系管理系统是如何实现客户管理的
中国移动协作型客户关系管理系统是实现客户管理的方法如下。
1、移动通信企业CRM分析1.1移动的顾客识别移动公司通过一系列技术手段深入了解自己的顾客,收集客户信息,根据客户的特征、购买记录等可得数据,找出谁是企业的潜在顾客,客户的需求是什么、哪类客户最有价值等,并把这些客户作为企业客户关系管理的实施对象,从而为企业成功实施提CRM供保障。
2、移动的顾客识别移动公司通过一系列技术手段深入了解自己的顾客,收集客户信息,根据客户的特征、购买记录等可得数据,找出谁是企业的潜在顾客,客户的需求是什么、哪类客户最有价值等,并把这些客户作为企业客户关系管理的实施对象,从而为企业成功实施提CRM供保障。