1、学员提交报名的数据,页面如下:
前面销售填写报名表提交后会生成学生报名的链接
学生报名的请求链接,在crm/urls.py中设置url
url(r'^customer/registration/(d+)$', views.stu_enrollment, name="stu_enrollment"),
在crm/view.py创建一个stu_enrollment函数
在sales目录下新建stu_enrollment.py
该页面表单有些数据是直接从数据库中取出来的,不做改变
创建Customer表单
1、创建一个Customer表单,readonly_fields变量是存储字段只读属性,exclude变量是django表单拥有的一个在前端不显示的属性
2、clean_{field}函数是表单专有的一个判断表单字段函数,利用clean_{field}函数后面必须的返回这个字段的值不然请求的时候这个表单字段的值为空(这个是之前不懂的时候遇到的bug)
3、只读的数据需要用请求的数据和数据库的数据做判断是否相等才不会被篡改,表单数据库中的值:instance.qq,表单请求过来的值:cleaned_data["qq"]
#crm/forms.py
from django.forms import ModelForm
from PerfectCRM.Perfectcrm.crm import models
class CustomerForm(ModelForm):
"""客户表单"""
def __new__(cls,*args,**kwargs):
#super(CustomerForm,self).__new__(*args,**kwargs)
# print("request.POST:",request.POST)
#表名,表对象值
for field_name,field_obj in cls.base_fields.items():
#print(field_name,dir(field_obj))
#给表输入框添加class
field_obj.widget.attrs['class'] = 'form-control'
if field_name in cls.Meta.readonly_fields:
#添加disabled属性
field_obj.widget.attrs['disabled'] = 'disabled'
return ModelForm.__new__(cls)
def clean_qq(self):
#不能修改的值取数据库中的值和页面的值相比较
if self.instance.qq != self.cleaned_data["qq"]:
self.add_error("qq","小样竟敢黑我小瞧我了")
else:
return self.instance.qq
def clean_source(self):
#不能修改的值取数据库中的值和页面的值相比较
if self.instance.source != self.cleaned_data["source"]:
#添加表单错误信息
self.add_error("source","小样竟敢黑我小瞧我了")
else:
return self.instance.source
def clean_consultant(self):
#不能修改的值取数据库中的值和页面的值相比较
if self.instance.consultant != self.cleaned_data["consultant"]:
self.add_error("consultant","小样竟敢黑我小瞧我了")
else:
return self.instance.consultant
def clean_name(self):
if not self.cleaned_data["name"]:
self.add_error("name","name不能为空")
else:
return self.cleaned_data["name"]
class Meta:
model =models.Customer
fields ='__all__'
#不在前端显示
exclude =["tags","content","memo","status","referral_from","consult_course"]
#只读属性
readonly_fields =["qq","consultant","source"]
在crm/view.py文件中返回Customers表单数据
1、之前学生报名链接的时效性用cache做的,获取他字符串random_str的值是否等于请求的值,如果不等于就返回url失效
2、判断前端请求过来是post请求
3、Customer表单请求的数据要和enroll已存的数据比较然后更新,如果表单数据正确则存储数据并且更新报名表中的contract_agreed字段值为True
4、利用字段status=1,学员已经报名成功,在前端筛选展示
def stu_enrollment(request,enroll_id,random_str):
"""学生报名"""
enroll_obj = models.Enrollment.objects.get(id=enroll_id)
#返回customer信息的时候的带他之前enroll的数据
#customer_form = CustomerForm(instance=enroll_obj.customer)
if cache.get(enroll_obj.id) == random_str:
if request.method == "POST":
#更新customer的数据请求和库里面的
customer_form = CustomerForm(request.POST,instance=enroll_obj.customer)
#如果数据有效就保存
if customer_form.is_valid():
customer_form.save()
enroll_obj.contract_agreed=True
enroll_obj.save()
return render(request,"sales/stuenrollment.html",{"status":1})
else:
#学员同意该合同
if enroll_obj.contract_agreed:
status=1
else:
status=0
customer_form = CustomerForm(instance=enroll_obj.customer)
return render(request,"sales/stuenrollment.html",{"customer_form":customer_form,
"enroll_obj":enroll_obj,
"status":status})
else:
return HttpResponse("url已经过期")
返回前端页面stuenrollment.html
1、判断如果status!=1表名不成功就返回报名页面,如果成功就返回报名成功的页面
2、由于要返回合同协议条款,需要后端处理,在crm新建一个crm_tags,合同里面可以利用.format填写固定存在的值
3、只能是选择同意合同才能够提交
4、disable属性的数据提交时是没有请求值的,得在提交时移除他的disable属性
{% extends 'base.html'%}
{% load crm_tags %}
{% block body %}
<div class="container">
<div class="panel panel-success">
<div class="panel-heading">
<h3>Panel title</h3>
</div>
{% if status != 1 %}
<div class="panel-body">
<span style="color: red">{{customer_form.errors}}</span>
<form class="form-horizontal" role="form" method="post" onsubmit="return RegisterFormCheck()">{% csrf_token %}
{%for field in customer_form%}
<div class="form-group">
<label class="col-sm-2 control-label">{{field.label}}</label>
<div class="col-sm-9">
{{field}}
</div>
</div>
{% endfor %}
<hr/>
<div class="form-group">
<label class="col-sm-2 control-label">所报课程</label>
<div class="col-sm-8">
{{enroll_obj.enrolled_class.course}}
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">课程学费</label>
<div class="col-sm-8">
{{enroll_obj.enrolled_class.course.price}}
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">课程开始时间</label>
<div class="col-sm-8">
{{enroll_obj.enrolled_class.start_date}}
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<pre style="height: 400px;overflow: auto">{% render_enroll_contract enroll_obj%}</pre>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="checkbox" name="contract_agreed">我已阅读完协议并同意所有条款
</div>
</div>
<div class="text-center">
<input type="submit" class="btn btn-info" value="提交">
</div>
</form>
</div>
{% else %}
<h2>感谢,报名表已提交,您的合同将很快被审核,即将开启激动的自我提升之旅</h2>
{% endif %}
</div>
</div>
<script>
function RegisterFormCheck() {
if($("form :checkbox").prop("checked")){
$("form").find("[disabled]").removeAttr("disabled");
return true;
}else{
alert("必须同意该协议");
return false;
}
}
</script>
{% endblock%}
#crm_tags
from django import template
from django.utils.safestring import mark_safe
from django.utils.timezone import datetime,timedelta
from django.core.exceptions import FieldDoesNotExist
register = template.Library()
@register.simple_tag
def render_enroll_contract(enroll_obj):
return enroll_obj.enrolled_class.contract.template.format(cunstomer_qq=enroll_obj.customer.qq,
enroll_course=enroll_obj.enrolled_class.course)
url的时效性
1、利用django的cache设置时效
2、利用string.ascii_lowercase+string.digits+random.sample产生随机的字符串
3、cache.set(字段名,字段值,时效)设置url的失效
4、cache.get(字段名),如果时效还在得到值,过期没有获取到值
前面的学生报名链接改成:
msg='''请将此链接发送给客户进行填写:
http://localhost:8000/crm/customer/registration/{enroll_obj_id}/{random_str}'''
设置时效的操作:
import string,random
from django.core.cache import cache
#报名生成的链接
random_str = ''.join(random.sample(string.ascii_lowercase+string.digits,8))
cache.set(enroll_obj.id,random_str,3600)
msgs["msg"] = msg.format(enroll_obj_id=enroll_obj.id,random_str=random_str)