(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>
(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>
报名流程
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为一对一的关系
流程
(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 %}
(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 %}
在线报名填表页面
修改只读字段会报错