zoukankan      html  css  js  c++  java
  • CRM客户关系管理系统(十一)

    第十一章、学员报名流程开发 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 %}

     在线报名填表页面

     修改只读字段会报错

     

  • 相关阅读:
    【测试】Testing as a Service (TaaS)
    【Git】git cherry-pick 使用
    【2021】开篇
    【Java】容器类的实现和互相转换
    【Testing】API Testing
    【WeeklySoftwareTesting】
    【Oracle】XMLTABLE介绍
    【Oracle】创建定时任务
    【Java】Retryer重试机制
    表格数据导出报表
  • 原文地址:https://www.cnblogs.com/derek1184405959/p/8985067.html
Copyright © 2011-2022 走看看