一、项目需求(使用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
三、开发中使用的相关技术:
Django\Bootstrap\Jquery等
四、项目各个功能的实现以及知识点:
1、自定义数据库表显示页面
- 页面模板使用:Bootstarp: http://v3.bootcss.com/examples/dashboard/
- base.html\index.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>
{% 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 %}
-
显示页面: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;width: 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 %}
- 页面的显示
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>
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})
注解:
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="#">«</a></li>#} {# <li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>#} {# #} </ul> </nav> </div> </div> {% endblock %}
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})
#__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
#__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
注解: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:过滤后的数据