• CRM客户关系管理系统知识点总结


    一、项目需求(使用PrecessOn)

    二、models.py

    from django.db import models
    from django.contrib.auth.models import User
    # Create your models here.
    
    
    class Customer(models.Model):
        '''客户信息表'''
        name = models.CharField(max_length=32,blank=True,null=True)
        qq = models.CharField(max_length=64,unique=True)
        qq_name = models.CharField(max_length=64,blank=True,null=True)
        phone = models.CharField(max_length=64,blank=True,null=True)
        source_choices = ((0,'转介绍'),
                          (1,'QQ群'),
                          (2,'官网'),
                          (3,'百度推广'),
                          (4,'51CTO'),
                          (5,'知乎'),
                          (6,'市场推广'),
                          )
    
        source = models.SmallIntegerField(choices=source_choices)
        referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True)
    
        consult_course = models.ForeignKey("Course",verbose_name="咨询课程")
        content = models.TextField(verbose_name="咨询详情")
        tags = models.ManyToManyField("Tag",blank=True,null=True)
        status_choices = ((0,'已报名'),
                          (1,'未报名'),
                          )
        status = models.SmallIntegerField(choices=status_choices,default=1)
        consultant = models.ForeignKey("UserProfile")
        memo = models.TextField(blank=True,null=True)
        date = models.DateTimeField(auto_now_add=True)
    
        def __str__(self):
            return self.qq
    
        class Meta:
            verbose_name ="客户表"
            verbose_name_plural ="客户表"
    
    class Tag(models.Model):
        name = models.CharField(unique=True,max_length=32)
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = "标签"
            verbose_name_plural = "标签"
    
    class CustomerFollowUp(models.Model):
        '''客户跟进表'''
        customer = models.ForeignKey("Customer")
        content = models.TextField(verbose_name="跟进内容")
        consultant = models.ForeignKey("UserProfile")
    
        intention_choices  = ((0,'2周内报名'),
                              (1,'1个月内报名'),
                              (2,'近期无报名计划'),
                              (3,'已在其它机构报名'),
                              (4,'已报名'),
                              (5,'已拉黑'),
                              )
        intention = models.SmallIntegerField(choices=intention_choices)
        date = models.DateTimeField(auto_now_add=True)
    
        def __str__(self):
            return "<%s : %s>" %(self.customer.qq,self.intention)
    
    
        class Meta:
            verbose_name = "客户跟进记录"
            verbose_name_plural = "客户跟进记录"
    
    class Course(models.Model):
        '''课程表'''
        name = models.CharField(max_length=64,unique=True)
        price = models.PositiveSmallIntegerField()
        period = models.PositiveSmallIntegerField(verbose_name="周期(月)")
        outline = models.TextField()
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = "课程表"
            verbose_name_plural = "课程表"
    
    class Branch(models.Model):
        '''校区'''
        name = models.CharField(max_length=128,unique=True)
        addr = models.CharField(max_length=128)
        def __str__(self):
            return self.name
    
    
        class Meta:
            verbose_name = "校区"
            verbose_name_plural = "校区"
    
    class ClassList(models.Model):
        '''班级表'''
        branch = models.ForeignKey("Branch",verbose_name="校区")
        course = models.ForeignKey("Course")
        class_type_choices = ((0,'面授(脱产)'),
                              (1,'面授(周末)'),
                              (2,'网络班')
                              )
        class_type = models.SmallIntegerField(choices=class_type_choices,verbose_name="班级类型")
        semester = models.PositiveSmallIntegerField(verbose_name="学期")
        teachers = models.ManyToManyField("UserProfile")
        start_date = models.DateField(verbose_name="开班日期")
        end_date = models.DateField(verbose_name="结业日期",blank=True,null=True)
    
        def __str__(self):
            return "%s %s %s" %(self.branch,self.course,self.semester)
    
        class Meta:
            unique_together = ('branch','course','semester')
            verbose_name_plural = "班级"
            verbose_name = "班级"
    
    class CourseRecord(models.Model):
        '''上课记录'''
        from_class = models.ForeignKey("ClassList",verbose_name="班级")
        day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)")
        teacher = models.ForeignKey("UserProfile")
        has_homework = models.BooleanField(default=True)
        homework_title = models.CharField(max_length=128,blank=True,null=True)
        homework_content = models.TextField(blank=True,null=True)
        outline = models.TextField(verbose_name="本节课程大纲")
        date = models.DateField(auto_now_add=True)
    
        def __str__(self):
            return "%s %s" %(self.from_class,self.day_num)
    
        class Meta:
            unique_together = ("from_class", "day_num")
            verbose_name_plural = "上课记录"
    
    
    class StudyRecord(models.Model):
        '''学习记录'''
        student = models.ForeignKey("Enrollment")
        course_record = models.ForeignKey("CourseRecord")
        attendance_choices = ((0,'已签到'),
                              (1,'迟到'),
                              (2,'缺勤'),
                              (3,'早退'),
                              )
        attendance = models.SmallIntegerField(choices=attendance_choices,default=0)
        score_choices = ((100,"A+"),
                         (90,"A"),
                         (85,"B+"),
                         (80,"B"),
                         (75,"B-"),
                         (70,"C+"),
                         (60,"C"),
                         (40,"C-"),
                         (-50,"D"),
                         (-100,"COPY"),
                         (0,"N/A"),
                         )
        score = models.SmallIntegerField(choices=score_choices,default=0)
        memo = models.TextField(blank=True,null=True)
        date = models.DateField(auto_now_add=True)
    
        def __str__(self):
            return "%s %s %s" %(self.student,self.course_record,self.score)
    
        class Meta:
            unique_together = ('student','course_record')
            verbose_name_plural = "学习记录"
    
    
    class Enrollment(models.Model):
        '''报名表'''
        customer = models.ForeignKey("Customer")
        enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级")
        consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问")
        contract_agreed = models.BooleanField(default=False,verbose_name="学员已同意合同条款")
        contract_approved = models.BooleanField(default=False,verbose_name="合同已审核")
        date = models.DateTimeField(auto_now_add=True)
    
        def __str__(self):
            return "%s %s" %(self.customer,self.enrolled_class)
    
        class Meta:
            unique_together = ("customer","enrolled_class")
            verbose_name_plural = "报名表"
    
    class Payment(models.Model):
        '''缴费记录'''
        customer = models.ForeignKey("Customer")
        course = models.ForeignKey("Course",verbose_name="所报课程")
        amount = models.PositiveIntegerField(verbose_name="数额",default=500)
        consultant = models.ForeignKey("UserProfile")
        date = models.DateTimeField(auto_now_add=True)
    
        def __str__(self):
            return "%s %s" %(self.customer,self.amount)
    
        class Meta:
            verbose_name_plural = "缴费记录"
    
    class UserProfile(models.Model):
        '''账号表'''
        user = models.OneToOneField(User)
        name = models.CharField(max_length=32)
        roles = models.ManyToManyField("Role",blank=True,null=True)
    
        def __str__(self):
            return self.name
    
    class Role(models.Model):
        '''角色表'''
        name = models.CharField(max_length=32,unique=True)
        menus = models.ManyToManyField("Menu",blank=True)
    
        def __str__(self):
            return self.name
        class Meta:
            verbose_name_plural = "角色"
    
    
    class Menu(models.Model):
        '''菜单'''
        name = models.CharField(max_length=32)
        url_name = models.CharField(max_length=64)
    
        def __str__(self):
            return self.name
    models.py

    三、开发中使用的相关技术:

      DjangoBootstrapJquery等

    四、项目各个功能的实现以及知识点:

    1、自定义数据库表显示页面

    • 页面模板使用:Bootstarp:     http://v3.bootcss.com/examples/dashboard/
    • base.htmlindex.html
      <!DOCTYPE html>
      <!-- saved from url=(0041)http://v3.bootcss.com/examples/dashboard/ -->
      <html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <meta name="description" content="">
          <meta name="author" content="">
          <!--link rel="icon" href="http://v3.bootcss.com/favicon.ico"-->
      
          <title>Oldboy PerfectCRM</title>
      
          <!-- Bootstrap core CSS -->
          <link href="/static/css/bootstrap.min.css" rel="stylesheet">
      
          <!-- Custom styles for this template -->
          <link href="/static/css/dashboard.css" rel="stylesheet">
      
          <!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
          <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
          <script src="/static/js/ie-emulation-modes-warning.js"></script>
      
      
        </head>
      {% block body %}
      
      
      {% endblock %}
      
      <!-- Bootstrap core JavaScript
      ================================================== -->
      <!-- Placed at the end of the document so the pages load faster -->
      <script src="/static/js/jquery.min.js"></script>
      <script src="/static/js/bootstrap.min.js"></script>
      <script src="/static/js/docs.min.js"></script>
      <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
      <script src="/static/js/ie10-viewport-bug-workaround.js"></script>
      
      
      </html>
      base.html
      {% extends 'base.html' %}
      
      {% block body %}
      <body>
      
      <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
        <div class="container-fluid">
          <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
              <span class="sr-only">Toggle navigation</span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Oldboy PefectCRM</a>
          </div>
          <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
      
              <li><a href="#">{{ request.user }}</a></li>
            </ul>
      
          </div>
        </div>
      </nav>
      
      <div class="container-fluid">
        <div class="row">
          <div class="col-sm-3 col-md-2 sidebar">
            <ul class="nav nav-sidebar">
              {% for  role in request.user.userprofile.roles.all %}
                {% for menu in role.menus.all %}
                  <li class=""><a href="{%  url  menu.url_name %}">{{ menu.name }}</a></li>
                {% endfor %}
              {% endfor %}
      
            </ul>
      
          </div>
          <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
           {% block page-content %}
            <h1 class="page-header">Dashboard</h1>
      
            <div class="row placeholders">
      
              <div class="col-xs-6 col-sm-3 placeholder">
                <img data-src="holder.js/200x200/auto/sky" class="img-responsive" alt="200x200" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxkZWZzLz48cmVjdCB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgZmlsbD0iIzBEOEZEQiIvPjxnPjx0ZXh0IHg9Ijc1LjUiIHk9IjEwMCIgc3R5bGU9ImZpbGw6I0ZGRkZGRjtmb250LXdlaWdodDpib2xkO2ZvbnQtZmFtaWx5OkFyaWFsLCBIZWx2ZXRpY2EsIE9wZW4gU2Fucywgc2Fucy1zZXJpZiwgbW9ub3NwYWNlO2ZvbnQtc2l6ZToxMHB0O2RvbWluYW50LWJhc2VsaW5lOmNlbnRyYWwiPjIwMHgyMDA8L3RleHQ+PC9nPjwvc3ZnPg==" data-holder-rendered="true">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div>
              <div class="col-xs-6 col-sm-3 placeholder">
                <img data-src="holder.js/200x200/auto/vine" class="img-responsive" alt="200x200" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxkZWZzLz48cmVjdCB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgZmlsbD0iIzM5REJBQyIvPjxnPjx0ZXh0IHg9Ijc1LjUiIHk9IjEwMCIgc3R5bGU9ImZpbGw6IzFFMjkyQztmb250LXdlaWdodDpib2xkO2ZvbnQtZmFtaWx5OkFyaWFsLCBIZWx2ZXRpY2EsIE9wZW4gU2Fucywgc2Fucy1zZXJpZiwgbW9ub3NwYWNlO2ZvbnQtc2l6ZToxMHB0O2RvbWluYW50LWJhc2VsaW5lOmNlbnRyYWwiPjIwMHgyMDA8L3RleHQ+PC9nPjwvc3ZnPg==" data-holder-rendered="true">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div>
            </div>
      
            <h2 class="sub-header">Section title</h2>
      
           {% endblock %}
          </div>
        </div>
      </div>
      
      
      
      </body>
      
      {% endblock %}
      index.html
    • 显示页面:table_index.html

      {%  extends 'base.html' %}
      {% load tags %}
      
      {% block body %}
      <body>
      
      <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
        <div class="container-fluid">
          <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
              <span class="sr-only">Toggle navigation</span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Oldboy PefectCRM</a>
          </div>
          <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
      
              <li><a href="#">{{ request.user }}</a></li>
            </ul>
      
          </div>
        </div>
      </nav>
      
      <div class="container " style="margin: 50px; auto">
          {% block container %}
          <div class="row">
              <div class="panel panel-info">
                <div class="panel-heading">
                  <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                  {{ table_list }}
                    {% for app_name,app_tables in table_list.items %}
      
                       <table class="table table-hover">
                          <thead>
                              <tr>
                                  <th>{{ app_name }}</th>
                              </tr>
                          </thead>
                          <tbody>
                              {% for table_name,admin  in app_tables.items %}
                                  <tr>
                                      <td>
                                          <a href="{% url 'table_objs' app_name table_name %}">
                                             {% render_app_name admin %}
                                          </a>
                                      </td>
                                      <td>add</td>
                                      <td>change</td>
                                  </tr>
                              {% endfor %}
                          </tbody>
                       </table>
                    {% endfor %}
      
                </div>
              </div>
          </div>
          {% endblock %}
      </div>
      
      
      </body>
      
      {% endblock %}
      table_index.html

    • 页面的显示
      1 from django.conf.urls import url,include
      2 from django.contrib import admin
      3 
      4 urlpatterns = [
      5     url(r'^king_admin/', include("king_admin.urls")),
      6 ]
      1 from django.conf.urls import url
      2 from king_admin import views
      3 
      4 urlpatterns = [
      5     url(r'^$', views.index,name="table_index"),
      6 ]
    • 注册要显示的表,自定义显示信息项king_admin.py

      #__author:  Administrator
      #date:  2017/1/5
      
      from crm import models
      
      
      enabled_admins = {}
      
      class BaseAdmin(object):
          list_display = []
          list_filters = []
          search_fields = []
          list_per_page = 20
          ordering = None
      
      class CustomerAdmin(BaseAdmin):
          list_display = ["id",'qq','name','source','consultant','consult_course','date','status']
          list_filters = ['source','consultant','consult_course','status','date']
          search_fields = ['qq','name',"consultant__name"]
      
          #model = models.Customer
          list_per_page = 5
          ordering = "qq"
      class CustomerFollowUpAdmin(BaseAdmin):
          list_display = ('customer','consultant','date')
      
      
      def register(model_class,admin_class=None):
          if model_class._meta.app_label not in enabled_admins:
              enabled_admins[model_class._meta.app_label] = {} #enabled_admins['crm'] = {}
          #admin_obj = admin_class()
          admin_class.model = model_class #绑定model 对象和admin 类
          enabled_admins[model_class._meta.app_label][model_class._meta.model_name] = admin_class
          #enabled_admins['crm']['customerfollowup'] = CustomerFollowUpAdmin
      
      
      register(models.Customer,CustomerAdmin)
      register(models.CustomerFollowUp,CustomerFollowUpAdmin)
      <div class="panel-body">
                  {{ table_list }}
                    {% for app_name,app_tables in table_list.items %}
      
                       <table class="table table-hover">
                          <thead>
                              <tr>
                                  <th>{{ app_name }}</th>
                              </tr>
                          </thead>
                          <tbody>
                              {% for table_name,admin  in app_tables.items %}
                                  <tr>
                                      <td>
                                          <a href="{% url 'table_objs' app_name table_name %}">
                                             {% render_app_name admin %}
                                          </a>
                                      </td>
                                      <td>add</td>
                                      <td>change</td>
                                  </tr>
                              {% endfor %}
                          </tbody>
                       </table>
                    {% endfor %}
      
                </div>
      HTML
      from django.shortcuts import render,redirect
      import importlib
      from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
      from king_admin.utils import  table_filter,table_sort,table_search
      # Create your views here.
      from king_admin import king_admin
      from king_admin.forms import create_model_form
      
      def index(request):
          #print(king_admin.enabled_admins['crm']['customerfollowup'].model )
          return render(request, "king_admin/table_index.html",{'table_list':king_admin.enabled_admins})
      
      
      def display_table_objs(request,app_name,table_name):
      
          print("-->",app_name,table_name)
          #models_module = importlib.import_module('%s.models'%(app_name))
          #model_obj = getattr(models_module,table_name)
          admin_class = king_admin.enabled_admins[app_name][table_name]
          #admin_class = king_admin.enabled_admins[crm][userprofile]
      
          #object_list = admin_class.model.objects.all()
          object_list,filter_condtions = table_filter(request,admin_class) #过滤后的结果
      
          object_list = table_search(request,admin_class,object_list)
      
      
          object_list,orderby_key = table_sort(request, admin_class, object_list) #排序后的结果
          print("orderby key ", orderby_key)
          paginator = Paginator(object_list, admin_class.list_per_page) # Show 25 contacts per page
      
          page = request.GET.get('page')
          try:
              query_sets = paginator.page(page)
          except PageNotAnInteger:
              # If page is not an integer, deliver first page.
              query_sets = paginator.page(1)
          except EmptyPage:
              # If page is out of range (e.g. 9999), deliver last page of results.
              query_sets = paginator.page(paginator.num_pages)
      
          return render(request,"king_admin/table_objs.html",{"admin_class":admin_class,
                                                              "query_sets":query_sets,
                                                              "filter_condtions":filter_condtions,
                                                              "orderby_key":orderby_key,
                                                              "previous_orderby": request.GET.get("o",''),
                                                              "search_text":request.GET.get('_q','')})
      
      def table_obj_add(request,app_name,table_name):
          admin_class = king_admin.enabled_admins[app_name][table_name]
          model_form_class = create_model_form(request,admin_class)
      
          if request.method == "POST":
              form_obj = model_form_class(request.POST)  #
              if form_obj.is_valid():
                  form_obj.save()
                  return  redirect(request.path.replace("/add/","/"))
          else:
              form_obj = model_form_class()
      
          return render(request, "king_admin/table_obj_add.html", {"form_obj": form_obj})
      
      def table_obj_change(request,app_name,table_name,obj_id):
      
          admin_class = king_admin.enabled_admins[app_name][table_name]
          model_form_class = create_model_form(request,admin_class)
      
          obj = admin_class.model.objects.get(id=obj_id)
          if request.method == "POST":
              form_obj = model_form_class(request.POST,instance=obj) #更新
              if form_obj.is_valid():
                  form_obj.save()
          else:
      
              form_obj = model_form_class(instance=obj)
      
          return render(request,"king_admin/table_obj_change.html",{"form_obj":form_obj})
      views.py

      注解:

      enabled_admins :register(model_class:表名,admin_class=None:表相关的类)  

           model_class._meta.app_label:相当于models.Customer._meta.app_label  结果为:app名:'crm'

        model_class._meta.model_name:相当于models.Customer._meta.model_name 结果:'customer'

           models.Customer._meta.verbose_name获取表的中文名

           admin_class.model = model_class相当于models.Customer

      enabled_admins[model_class._meta.app_label][model_class._meta.model_name] = admin_class  实例化类 (CustomerAdmin) 

      table_list:   table_list = king_admin.enabled_admins  当前已经注册的表, enabled_admins 中存的app、表名 

      页面跳转的实现:
      <a href="{% url 'table_objs' app_name table_name %}">
      url(r'^(w+)/(w+)/$', views.display_table_objs,name="table_objs"),
      相当于:def table_objs((w+),(w+))的两个参数为app_name table_name

      表详细信息显示页面:
      
      
      {%  extends 'king_admin/table_index.html' %}
      {% load tags %}
      
      
      
      
      {% block container %}
          {{ admin_class.list_display }}
          <div class="panel panel-info">
                <div class="panel-heading">
                  <h3 class="panel-title">{% get_model_name admin_class %}
                      <a href="{{ request.path }}add/" class="pull-right">Add</a>
                  </h3>
      
                </div>
                <div class="panel-body">
                     <div class="row">
                      <form class="" method="get">
                        {% for filter_field in admin_class.list_filters %}
                          <div class="col-lg-2">
                          <span>{{ filter_field }}</span>
                          {% render_filter_ele filter_field admin_class filter_condtions %}
                          </div>
      
                        {% endfor %}
      
                          <button type="SUBMIT" class="btn btn-success">检索</button>
      
                       <hr>
                        <div class="row">
                            <div class="col-lg-2" >
                              <input type="search" name="_q" class="form-control" style="margin-left:15px" value="{{ search_text }}" placeholder="search by {% for search_field in admin_class.search_fields %}{{ search_field }},{% endfor %} ">
                            </div>
                            <div class="col-lg-2" >
                              <button type="SUBMIT" class="btn btn-success">search</button>
                            </div>
                        </div>
                      </form>
      
                     </div>
      
                    <table class="table table-hover">
                        <thead>
                          <tr>
                              {% for column in admin_class.list_display %}
                                  {% build_table_header_column column orderby_key filter_condtions %}
                              {% endfor %}
                          </tr>
                        </thead>
                        <tfoot>
                          <tr>
                              <td>总计{{ query_sets.paginator.count }}条</td></tr>
                        </tfoot>
                        <tbody>
      {#                    {% get_query_sets  admin_class as query_sets %}#}
                          {% for obj in query_sets %}
                          <tr>
                              {% build_table_row request obj admin_class %}
                          </tr>
                          {% endfor %}
                        </tbody>
      
                    </table>
      
      
      
                <nav>
                    <ul class="pagination">
                        {% if query_sets.has_previous %}
                              <li class=""><a href="?page={{ query_sets.previous_page_number }}">上页</a></li>
                        {% endif %}
      {#                   <li class="active"><a>{{ query_sets.number }}</a></li>#}
      
      {#                  {% for loop_counter in query_sets.paginator.page_range %}#}
      {#                        {% render_page_ele  loop_counter query_sets filter_condtions%}#}
      {#                  {% endfor %}#}
      
                        {% build_paginators query_sets   filter_condtions  previous_orderby search_text%}
      
                        {% if query_sets.has_next %}
                              <li class=""><a href="?page={{ query_sets.next_page_number }}">下页</a></li>
                        {% endif %}
      
      
      {#                <li class="disabled"><a href="#">&laquo;</a></li>#}
      {#                <li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>#}
      {#                #}
                    </ul>
                </nav>
      
      
      
                </div>
          </div>
      {% endblock %}
      table_objs.html
      
      
      from django.shortcuts import render,redirect
      import importlib
      from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
      from king_admin.utils import  table_filter,table_sort,table_search
      # Create your views here.
      from king_admin import king_admin
      from king_admin.forms import create_model_form
      
      def index(request):
          #print(king_admin.enabled_admins['crm']['customerfollowup'].model )
      
          return render(request, "king_admin/table_index.html",{'table_list':king_admin.enabled_admins})
      
      
      def display_table_objs(request,app_name,table_name):
      
          print("-->",app_name,table_name)
          #models_module = importlib.import_module('%s.models'%(app_name))
          #model_obj = getattr(models_module,table_name)
          admin_class = king_admin.enabled_admins[app_name][table_name]
          #admin_class = king_admin.enabled_admins[crm][userprofile]
      
          #object_list = admin_class.model.objects.all()
          object_list,filter_condtions = table_filter(request,admin_class) #过滤后的结果
      
          object_list = table_search(request,admin_class,object_list)
      
      
          object_list,orderby_key = table_sort(request, admin_class, object_list) #排序后的结果
          print("orderby key ", orderby_key)
          paginator = Paginator(object_list, admin_class.list_per_page) # Show 25 contacts per page
      
          page = request.GET.get('page')
          try:
              query_sets = paginator.page(page)
          except PageNotAnInteger:
              # If page is not an integer, deliver first page.
              query_sets = paginator.page(1)
          except EmptyPage:
              # If page is out of range (e.g. 9999), deliver last page of results.
              query_sets = paginator.page(paginator.num_pages)
      
          return render(request,"king_admin/table_objs.html",{"admin_class":admin_class,
                                                              "query_sets":query_sets,
                                                              "filter_condtions":filter_condtions,
                                                              "orderby_key":orderby_key,
                                                              "previous_orderby": request.GET.get("o",''),
                                                              "search_text":request.GET.get('_q','')})
      
      def table_obj_add(request,app_name,table_name):
          admin_class = king_admin.enabled_admins[app_name][table_name]
          model_form_class = create_model_form(request,admin_class)
      
          if request.method == "POST":
              form_obj = model_form_class(request.POST)  #
              if form_obj.is_valid():
                  form_obj.save()
                  return  redirect(request.path.replace("/add/","/"))
          else:
              form_obj = model_form_class()
      
          return render(request, "king_admin/table_obj_add.html", {"form_obj": form_obj})
      
      def table_obj_change(request,app_name,table_name,obj_id):
      
          admin_class = king_admin.enabled_admins[app_name][table_name]
          model_form_class = create_model_form(request,admin_class)
      
          obj = admin_class.model.objects.get(id=obj_id)
          if request.method == "POST":
              form_obj = model_form_class(request.POST,instance=obj) #更新
              if form_obj.is_valid():
                  form_obj.save()
          else:
      
              form_obj = model_form_class(instance=obj)
      
          return render(request,"king_admin/table_obj_change.html",{"form_obj":form_obj})
      views
      #__author:  Administrator
      #date:  2017/1/5
      
      from django import template
      from django.utils.safestring import mark_safe
      from django.utils.timezone import datetime,timedelta
      register = template.Library()
      
      @register.simple_tag
      def render_app_name(admin_class):
          return admin_class.model._meta.verbose_name
      
      @register.simple_tag
      def get_query_sets(admin_class):
          return admin_class.model.objects.all()
      
      @register.simple_tag
      def build_table_row(request, obj,admin_class):
          row_ele = ""
          for index,column in enumerate(admin_class.list_display):
              field_obj = obj._meta.get_field(column)
              if field_obj.choices:#choices type
                  column_data = getattr(obj,"get_%s_display" % column)()
              else:
                  column_data = getattr(obj,column)
      
              if type(column_data).__name__ == 'datetime':
                  column_data = column_data.strftime("%Y-%m-%d %H:%M:%S")
      
              if index == 0: #add a tag, 可以跳转到修改页
                  column_data = "<a href='{request_path}{obj_id}/change/'>{data}</a>".format(request_path=request.path,
                                                                                              obj_id=obj.id,
                                                                                              data=column_data)
              row_ele += "<td>%s</td>" % column_data
      
          return mark_safe(row_ele)
      
      
      @register.simple_tag
      def  build_paginators(query_sets,filter_condtions,previous_orderby,search_text):
          '''返回整个分页元素'''
          page_btns = ''
          filters = ''
          for k,v in filter_condtions.items():
              filters += "&%s=%s" %(k,v)
      
      
          added_dot_ele = False #
          for page_num in query_sets.paginator.page_range:
              if page_num < 3 or page_num > query_sets.paginator.num_pages -2 
                      or abs(query_sets.number - page_num) <= 2: #代表最前2页或最后2页 #abs判断前后1页
                  ele_class = ""
                  if query_sets.number == page_num:
                      added_dot_ele = False
                      ele_class = "active"
                  page_btns += '''<li class="%s"><a href="?page=%s%s&o=%s&_q=%s">%s</a></li>''' % (
                  ele_class, page_num, filters,previous_orderby, search_text,page_num)
              # elif abs(query_sets.number - page_num) <= 1: #判断前后1页
              #     ele_class = ""
              #     if query_sets.number == page_num:
              #         added_dot_ele = False
              #         ele_class = "active"
              #     page_btns += '''<li class="%s"><a href="?page=%s%s">%s</a></li>''' % (
              #     ele_class, page_num, filters, page_num)
              else: #显示...
                  if added_dot_ele == False: #现在还没加...
                      page_btns += '<li><a>...</a></li>'
                      added_dot_ele = True
      
      
          return mark_safe(page_btns)
      
      @register.simple_tag
      def render_page_ele(loop_counter,query_sets,filter_condtions):
          filters = ''
          for k,v in filter_condtions.items():
              filters += "&%s=%s" %(k,v)
      
          if loop_counter <3 or loop_counter > query_sets.paginator.num_pages -2 : #代表这是前2页 or 最后2页
              ele_class = ""
              if query_sets.number == loop_counter:
                  ele_class = "active"
              ele = '''<li class="%s"><a href="?page=%s%s">%s</a></li>''' %(ele_class,loop_counter,filters,loop_counter)
      
              return mark_safe(ele)
      
          if abs(query_sets.number - loop_counter) <= 1:
              ele_class = ""
              if query_sets.number == loop_counter:
                  ele_class = "active"
              ele = '''<li class="%s"><a href="?page=%s%s">%s</a></li>''' %(ele_class,loop_counter,filters,loop_counter)
      
              return mark_safe(ele)
          else:
              return '...'
          return ''
      
      
      @register.simple_tag
      def render_filter_ele(filter_field,admin_class,filter_condtions):
          #select_ele = '''<select class="form-control" name='%s' ><option value=''>----</option>''' %filter_field
          select_ele = '''<select class="form-control" name='{filter_field}' ><option value=''>----</option>'''
          field_obj = admin_class.model._meta.get_field(filter_field)
          if field_obj.choices:
              selected = ''
              for choice_item in field_obj.choices:
                  print("choice",choice_item,filter_condtions.get(filter_field),type(filter_condtions.get(filter_field)))
                  if filter_condtions.get(filter_field) == str(choice_item[0]):
                      selected ="selected"
      
                  select_ele += '''<option value='%s' %s>%s</option>''' %(choice_item[0],selected,choice_item[1])
                  selected =''
      
          if type(field_obj).__name__ == "ForeignKey":
              selected = ''
              for choice_item in field_obj.get_choices()[1:]:
                  if filter_condtions.get(filter_field) == str(choice_item[0]):
                      selected = "selected"
                  select_ele += '''<option value='%s' %s>%s</option>''' %(choice_item[0],selected,choice_item[1])
                  selected = ''
          if type(field_obj).__name__ in ['DateTimeField','DateField']:
              date_els = []
              today_ele = datetime.now().date()
              date_els.append(['今天', datetime.now().date()])
              date_els.append(["昨天",today_ele - timedelta(days=1)])
              date_els.append(["近7天",today_ele - timedelta(days=7)])
              date_els.append(["本月",today_ele.replace(day=1)])
              date_els.append(["近30天",today_ele - timedelta(days=30)])
              date_els.append(["近90天",today_ele - timedelta(days=90)])
              date_els.append(["近180天",today_ele - timedelta(days=180)])
              date_els.append(["本年",today_ele.replace(month=1,day=1)])
              date_els.append(["近一年",today_ele  - timedelta(days=365)])
      
              selected = ''
              for item in date_els:
                  select_ele += '''<option value='%s' %s>%s</option>''' %(item[1],selected,item[0])
      
      
              filter_field_name = "%s__gte" % filter_field
      
          else:
              filter_field_name = filter_field
          select_ele += "</select>"
          select_ele = select_ele.format(filter_field=filter_field_name)
      
          return mark_safe(select_ele)
      
      @register.simple_tag
      def  build_table_header_column(column,orderby_key,filter_condtions):
          filters = ''
          for k,v in filter_condtions.items():
              filters += "&%s=%s" %(k,v)
      
          ele = '''<th><a href="?{filters}&o={orderby_key}">{column}</a>
          {sort_icon}
          </th>'''
          if orderby_key:
              if orderby_key.startswith("-"):
                  sort_icon = '''<span class="glyphicon glyphicon-chevron-up"></span>'''
              else:
                  sort_icon = '''<span class="glyphicon glyphicon-chevron-down"></span>'''
      
              if orderby_key.strip("-") == column: #排序的就是这个字段
                  orderby_key =orderby_key
              else:
                  orderby_key = column
                  sort_icon = ''
      
          else:  #没有排序
              orderby_key = column
              sort_icon = ''
      
          ele = ele.format(orderby_key=orderby_key, column=column,sort_icon=sort_icon,filters=filters)
          return mark_safe(ele )
      
      
      @register.simple_tag
      def get_model_name(admin_class):
      
          return admin_class.model._meta.verbose_name
      tags.py
      #__author:  Administrator
      #date:  2017/1/5
      from django.db.models import Q
      
      def table_filter(request,admin_class):
          '''进行条件过滤并返回过滤后的数据'''
          filter_conditions = {}
          keywords = ['page','o','_q']
          for k,v in request.GET.items():
              if k in keywords:#保留的分页关键字 and 排序关键字
                  continue
              if v:
                  filter_conditions[k] =v
          print("filter coditions",filter_conditions)
      
          return admin_class.model.objects.filter(**filter_conditions).
                     order_by("-%s" % admin_class.ordering if admin_class.ordering else  "-id"),
                     filter_conditions
      
      def table_sort(request,admin_class,objs):
          orderby_key = request.GET.get("o")
          if orderby_key:
              res = objs.order_by(orderby_key)
              if orderby_key.startswith("-"):
                  orderby_key = orderby_key.strip("-")
              else:
                  orderby_key = "-%s"%orderby_key
          else:
              res = objs
          return res,orderby_key
      
      def table_search(request,admin_class,object_list):
          search_key = request.GET.get("_q","")
          q_obj = Q()
          q_obj.connector = "OR"
          for column in admin_class.search_fields:
              q_obj.children.append(("%s__contains"%column, search_key))
      
          res = object_list.filter(q_obj)
          return res
      utils.py

       注解:admin_class = king_admin.enabled_admins[app_name][table_name] 相当于:admin_class = {'crm':{'Customer':" ",'CustomerFollow':" "]}

      request.GET:获取网址红色的部分:http://127.0.0.1:8000/king_admin/crm/customer/?source=0&consultant=1&consult_course=1&status=0&date__gte=&_q=
      以字典的形式展示:{'date__gte': [''], 'consult_course': ['1'], 'status': ['0'], 'source': ['0'], 'consultant': ['1'], '_q': ['']}>
      filter coditions {'source': '0', 'status': '0', 'consult_course': '1', 'consultant': '1'}


      admin_class.model.objects.filter(**filter_conditions).order_by("-%s" % admin_class.ordering if admin_class.ordering else "-id"),
      order_by:以" "分组   (**filter_conditions):查找条件字典格式       

      filter_conditions:过滤后的数据




      
      
  • 相关阅读:
    c++语言 运算符重载 使用重载运算符实现类的加法运算
    c++语言 类模板的使用 类模板的实现
    C++语言 通过类模板实现加法计算器
    C++语言 对动物的行为实现多态
    c++语言 友元类和友元方法 将普通函数声明为友元函数
    C++语言 通过构造函数初始化学生信息
    c++语言 静态成员数据和静态方法
    欧拉回路心得
    POJ2965 The Pilots Brothers' refrigerator(枚举)
    HDU1269 迷宫城堡(有向图的强连通分量(scc))
  • 原文地址:https://www.cnblogs.com/shiluoliming/p/6735969.html
Copyright © 2020-2023  润新知