第十一章、学员报名流程开发 1

11.1.面包屑的制作

Boorstrap路径导航条

(1)table_obj_list.html页面面包屑

def table_obj_list

返回数据改成locals()

table_obj_list.html

kingadmin_tags.py

@register.simple_tag
def get_model_verbose_name(admin_class): return admin_class.model._meta.verbose_name

(2)change页面的面包屑

table_obj_change.html

<ol class="breadcrumb">
<li><a href="/kingadmin/">Home</a></li>
<li><a href="/kingadmin/{{ app_name }}">{{ app_name }}</a></li>
<li><a href="/kingadmin/{{ app_name }}/{{ model_name }}/">{% get_model_verbose_name admin_class %}</a></li>
<li class="active">{{ form_obj.instance }}</li>
</ol>
<h4 class="page-header">修改{{ form_obj.instance }}</h4>

(3)add页面的面包屑

因为add和change共用tags和html。所以要添加判断是add还是change

table__obj_change_component.html

kingadmin_tags.py

table_obj_add.html

 <ol class="breadcrumb">
<li><a href="/kingadmin/">Home</a></li>
<li><a href="/kingadmin/{{ app_name }}">{{ app_name }}</a></li>
<li><a href="/kingadmin/{{ app_name }}/{{ model_name }}/">{% get_model_verbose_name admin_class %}</a></li>
<li class="active">ADD {{ model_name }}</li>
</ol> <h2 class="page-header">{% get_model_name admin_class %}</h2>
<h4 class="page-header">添加{% get_model_name admin_class %}</h4>

11.2.报名流程和models设计

(1)后台修改左侧“客户库”的url

(2)左侧menu菜单添加“active”样式

kingadmin/index.html

如果当前的url 跟menu的url_name就添加“active”

 <ul class="nav nav-sidebar">
{% for role in request.user.userprofile.role.select_related %}
{% for menu in role.menus.select_related %}
{% if request.path == menu.url_name %}
<li class="active"><a href="{% if menu.url_type == 0 %}{{ menu.url_name }}{% else %}{% url menu.url_name %}{% endif %}">{{ menu.name }}</a></li>
{% else %}
<li ><a href="{% if menu.url_type == 0 %}{{ menu.url_name }}{% else %}{% url menu.url_name %}{% endif %}">{{ menu.name }}</a></li>
{% endif %}
{% endfor %}
{% endfor %}
</ul>

报名流程

  • 销售   发起报名流程,选择班级,发报名链接给学员
  • 学员   填写在线报名表,提交gerenxinxi,上传证件信息,同意培训协议
  • 销售    审核报名表,审核通过后,创建一条缴费记录,自动把学员添加到相应的班级,报名成功

models设计

添加三张表 crm/models.py

class ContractTemplate(models.Model):
'''存储合同模板'''
name = models.CharField(max_length=64)
content = models.TextField()
date = models.DateField(auto_now_add=True) class StudentEnrollment(models.Model):
"""学员报名表"""
customer = models.ForeignKey('CustomerInfo',on_delete=models.CASCADE)
class_grade = models.ForeignKey('ClassList',on_delete=models.CASCADE)
consultant = models.ForeignKey('UserProfile',on_delete=models.CASCADE)
contract_agreed = models.BooleanField(default=False)
contract_signed_date = models.DateTimeField(blank=True,null=True)
contract_approved = models.BooleanField(default=False)
consultant_approved_date = models.DateTimeField('合同审核时间',blank=True,null=True) class Meta:
unique_together = ('customer','class_grade') def __str__(self):
return '%s'% self.customer class PaymentRecord(models.Model):
'''存储学员缴费记录'''
enrollment = models.ForeignKey('StudentEnrollment',on_delete=models.CASCADE)
payment_type_choices = ((0,'报名费'),(1,'学费'),(2,'退费'))
payment_type = models.SmallIntegerField(choices=payment_type_choices,default=0)
amount = models.IntegerField('费用',default=500)
consultant = models.ForeignKey('UserProfile',on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True) def __str__(self):
return '%s' %self.enrollment

班级关联合同表

修改student跟customer为一对一的关系

11.3.报名页面

流程

  • 销售填写客户跟班级,点“下一步”提交
  • 后台获取到客户id和班级id,在数据库中创建记录,并生成一个报名链接,返回到前端
  • 前端显示报名链接,然后销售把报名链接发给用户

(1)crm/urls.py

# crm/urls.py

from django.conf.urls import url,include
from crm import views urlpatterns = [
url(r'^$', views.dashboard,name='sales_dashboard'),
#学员报名
url(r'^stu_enrollment/$', views.stu_enrollment,name='stu_enrollment'),
]

(2)crm/views.py

@login_required
def stu_enrollment(request): customers = models.CustomerInfo.objects.all()
class_lists = models.ClassList.objects.all() if request.method == 'POST':
#获取提交的客户id和班级id,然后生成报名链接
customer_id = request.POST.get('customer_id')
class_grade_id = request.POST.get('class_grade_id')
enrollment_obj = models.StudentEnrollment.objects.create(
customer_id = customer_id,
class_grade_id = class_grade_id,
consultant_id = request.user.userprofile.id
)
#生成链接返回到前端
enrollment_link = "http://localhost:8000/crm/enrollment/%s"% enrollment_obj.id return render(request,'crm/stu_enrollment.html',locals())

(3)新建templates/crm/stu_enrollment.html

crm/index.html

crm/stu_enrollment.html

{#templates/crm/stu_enrollment.html#}

{% extends 'index.html' %}

{% block right-content-container %}

    <h3>学员报名页</h3>

<form class="form-horizontal" method="post">
{% csrf_token %}
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">客户</label>
<div class="col-sm-10">
<select name="customer_id" class="form-control">
{% for customer in customers %}
<option value="{{ customer.id }}">{{ customer }}</option>
{% endfor %}
</select>
</div>
</div> <div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">报名班级</label>
<div class="col-sm-10">
<select name="class_grade_id" class="form-control">
{% for class_grade in class_lists %}
<option value="{{ class_grade.id }}">{{ class_grade }}</option>
{% endfor %}
</select>
</div>
</div> <input type="submit" class="btn btn-success pull-right" value="下一步"> </form> {% if enrollment_link %}
<p>请将此报名链接复制并发送给学员填写 {{ enrollment_link }}</p>
{% endif %} {% endblock %}

11.4.学员填写报名信息

  • 添加学员注册url
  • 添加CustomerInfo字段,身份证信息,紧急联络人,性别
  • 有些字段是只读的,填写信息的时候不能修改,因为如果设置了只读(添加属性disabled=true),提交的时候会报这些字段为空,导致提交错误
  • 所以在前段添加了js代码,BeforeFormSubmit  在提交前去掉disable=true(因为数据库中有默认值,提交的时候就不会报错)
  • 防止用户通过前端改html代码的方式改只读字段的信息,所以在form.py里面添加了一个自定义的验证方法(clean),如果只读字段提交的时候信息跟数据库中默认的不一样,就报错

(1)crm/urls.py

# crm/urls.py

from django.conf.urls import url,include
from crm import views urlpatterns = [
url(r'^$', views.dashboard,name='sales_dashboard'),
#学员报名
url(r'^stu_enrollment/$', views.stu_enrollment,name='stu_enrollment'),
#学员注册
url(r'^enrollment/(\d+)/$', views.enrollment,name='enrollment'),
]

(2)crm/models.py

CustomerInfo表 添加字段

(3)crm/form.py

# crm/form.py

from django.forms import ModelForm
from crm import models
from django import forms class CustomerForm(ModelForm):
class Meta:
model = models.CustomerInfo
fields = "__all__"
#不显示的字段
exclude = ['consult_content','status','consult_courses']
#只读的字段
readonly_fields = ['contact_type','contact','consultant','referral_from','source'] #django是通过“__new__”方法,找到ModelForm里面的每个字段的,然后循环出每个字段添加自定义样式
def __new__(cls, *args, **kwargs):
#cls.base_fields是一个元祖,里面是 所有的 【(字段名,字段的对象),(),()】
for field_name in cls.base_fields:
field_obj = cls.base_fields[field_name]
#添加属性
field_obj.widget.attrs.update({'class':'form-control'}) if field_name in cls.Meta.readonly_fields:
field_obj.widget.attrs.update({'disabled':'true'})
return ModelForm.__new__(cls) #只读字段不让用户通过浏览器改html代码的方式改
def clean(self):
# 表单级别的错误
if self.errors:
raise forms.ValidationError(("Please fix errors before re-submit."))
# means this is a change form ,should check the readonly fields
if self.instance.id is not None:
#取出只读字段,是一个字符串形式
for field in self.Meta.readonly_fields:
#通过反射取出字段的值(数据库里的数据)
old_field_val = getattr(self.instance, field)
#提交过来的数据
form_val = self.cleaned_data.get(field)
#如果两个数据不匹配
if old_field_val != form_val:
#就提示只读字段不能修改
#add_error是字段级别的错误
self.add_error(field, "Readonly Field: field should be '{value}' ,not '{new_value}' ". \
format(**{'value': old_field_val, 'new_value': form_val}))

(4)crm/views.py

def enrollment(request,enrollment_id):
'''学员在线报名表地址''' enrollment_obj = models.StudentEnrollment.objects.get(id=enrollment_id) if request.method == 'POST':
customer_form = form.CustomerForm(instance=enrollment_obj.customer,data=request.POST)
if customer_form.is_valid():
customer_form.save()
return HttpResponse("你已成功提交报名信息,请等待审核,欢迎加入仙剑奇侠传")
else:
customer_form = form.CustomerForm(instance=enrollment_obj.customer) return render(request,'crm/enrollment.html',locals())

(4)crm/enrollment.html

{#templates/crm/enrollment.html#}

{% extends 'index.html' %}

{% block body %}

    <div class="container">
<h3>仙剑奇侠传|学员报名</h3> <div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">学员在线报名</h3>
</div> <div class="panel-body"> <form class="form" method="post" onsubmit="return BeforeFormSubmit(this)">
{% csrf_token %}
{% for field in customer_form %}
<div class="form-group col-lg-6">
<label class="col-sm-2 control-label">{{ field.label }}</label>
<div class="col-sm-10">
{{ field }}
<span style="color: red;">{{ field.errors.0 }}</span>
</div>
</div>
{% endfor %} <div class="form-group col-lg-6">
<label class="col-sm-2 control-label">报名班级</label>
<div class="col-sm-10">
{{ enrollment_obj.class_grade }}
</div>
</div> <div class="form-group col-lg-6">
<label class="col-sm-2 control-label">学费</label>
<div class="col-sm-10">
{{ enrollment_obj.class_grade.course.price }}
</div>
</div> <div class="col-sm-offset-11 col-sm-2">
<input type="submit" class="btn btn-success " value="提交">
</div> </form> </div> <div class="panel-footer"><a href="http://www.cnblogs.com/derek1184405959/">zhang_derek</a></div>
</div> </div> <script> function BeforeFormSubmit(ele) {
$(":disabled").removeAttr("disabled");
} </script> {% endblock %}

在线报名填表页面

 修改只读字段会报错

CRM客户关系管理系统(十一)的更多相关文章

  1. Django CRM客户关系管理系统

    CRM需求分析 随着信息化时代带来的科技创新,CRM客户关系管理系统带来的效益在已经成为很多企业提高竞争优势的一分部,CRM客户关系管理系统将企业管理和客户关系管理集成到统一的平台,其系统功能主要体现 ...

  2. CRM 客户关系管理系统

    CRM(Customer Relationship Manager)客户关系管理系统 企业为提高核心竞争力,利用相应的信息技术以及互联网技术协调企业与顾客间在销售.营销和服务上的交互,从而提升其管理方 ...

  3. CRM客户关系管理系统 北京易信软科信息技术有限公司

    北京易信软科信息技术有限公司 推出大型erp系统,库存管理系统,客户关系管理系统,车辆登记管理系统,员工管理系统,采购管理系统,销售管理系统,为您的企业提供最优质的产品服务 北京易信软科您可信赖的北京 ...

  4. CRM客户关系管理系统-需求概设和详设

    大概设计 大概设计就是对需求进行一个整体性分析,把需要实现的功能都列出来,对于客户关系管理系统,我们需要从角色出发,从而确定有哪些需求,最好是画个思维导图 首先我们是为培训学校这么一个场景来开发的,所 ...

  5. Django项目:CRM(客户关系管理系统)--70--60PerfectCRM实现CRM学生上课记录

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

  6. Django项目:CRM(客户关系管理系统)--58--48PerfectCRM实现CRM客户报名流程学生合同

    # sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...

  7. CRM客户关系管理系统有哪些优缺点?

    CRM系统不仅仅是一种技术,也是面向企业的客户管理系统.客户关系管理软件可以帮助销售员快速地找到客户信息,帮助销售员跟踪客户直到完成订单.为提高企业销售效率,CRM被越来越多的企业所采用. 那么,作为 ...

  8. CRM客户关系管理系统(一)

    第一章.CRM介绍和开发流程 1.1.CRM简介 客户关系管理(CRM) 客户关系管理(customer relationship management)的定义是:企业为提高核心竞争力,利用相应的信息 ...

  9. Django项目:CRM(客户关系管理系统)--84--74PerfectCRM实现CRM权限和权限组限制访问URL

    #models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...

  10. Django项目:CRM(客户关系管理系统)--85--75PerfectCRM实现CRM扩展权限

    # sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...

随机推荐

  1. [python] 带有参数并且传递参数的装饰器

    场景时这样的,我有个一大堆任务,我要给这些任务计时,入库.就需要一个带有参数的装饰器来记录任务名称, 在任务执行前和执行之后都需要记录任务当时执行的时刻. #-*- encoding=utf-8 -* ...

  2. Java虚拟机定义

    虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java虚拟机有自己完善的硬体架构,如处理器.堆栈.寄存器等,还具有相应的指令系统.JVM屏蔽了与具体操作系统平台相关的 ...

  3. Android开发学习之路--Content Provider之初体验

    天气说变就变,马上又变冷了,还好空气不错,阳光也不错,早起上班的车上的人也不多,公司来的同事和昨天一样一样的,可能明天会多一些吧,那就再来学习android吧.学了两个android的组件,这里学习下 ...

  4. Cocos2D iOS之旅:如何写一个敲地鼠游戏(三):素材最终解决方法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  5. 数据库隔离级别(mysql+Spring)与性能分析

     数据库隔离级别与Spring配置事务的联系及性能影响,以下是个人理解,如果有瑕疵请及时指正.   这里以mysql为例,先明确以下几个问题: 一.一般项目如果不自己配置事务的话,一般默认的是au ...

  6. 【翻译】在Ext JS 6通用应用程序中使用既共享又特定于视图的代码

    原文:Using Both Shared and View-Specific Code in an Ext JS 6 Universal App 在本文,在展示如何编写Ext JS 6通用应用程序代码 ...

  7. 为什么会存在using filesort

    当使用explain分析SQL时常常会遇到extra的其中一值为using filesort,如: PRIMARY KEY (`id`),   KEY `uid` (`uid`) explain se ...

  8. web安全认证机制知多少

    如今web服务随处可见,成千上万的web程序被部署到公网上供用户访问,有些系统只针对指定用户开放,属于安全级别较高的web应用,他们需要有一种认证机制以保护系统资源的安全,本文将探讨五种常用的认证机制 ...

  9. Ubuntu 16.04 LTS今日发布

    Ubuntu 16.04 LTS今日发布 Ubuntu16.04 LTS 发布日期已正式确定为 2016 年 4 月 21 日,代号为 Xenial Xerus.Ubuntu16.04 将是非常受欢迎 ...

  10. (NO.00002)iOS游戏精灵战争雏形(十)

    到目前为止,子弹是有去无回.如果子弹击中目标或者飞出屏幕,那么子弹也就没必要存在了. 这里的不存在不是把它从屏幕中删除,因为前面提到了子弹缓存的作用,所以这里仅仅将其设置为不可见就可以了. 首先处理飞 ...