CRM客户关系管理系统(三)
第四章、kingadmin开发设计
4.1.kingadmin设计
django admin注册model的写法
crm/admin.py
class CustomerAdmin(admin.ModelAdmin):
#显示
list_display = ['name','source','contact_type','contact','consultant','consult_content','status','date']
#过滤
list_filter = ['source','consultant','status','date']
#搜索,consultant是外键,必须加“__字段名”
search_fields = ['contact','consultant__name'] admin.site.register(models.CustomerInfo,CustomerAdmin)
后台显示
这是后台显示的样子,如果我们想让前端也显示类似这样的页面该怎么做呢?这就需要照django自带的admin写法,自己自定义个kingadmin(模仿admin)
kingadmin
(1)创建app kingadmin
python manage.py startapp kingadmin
添加到settings的INSTALL_APPS里面
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crm',
'kingadmin',
]
因为想让kingadmin app以后可以直接移植到其它项目中,所以在kingadmin目录下单独创建templates/kingadmin和static目录,把之前的静态文件和模板拷贝进去
(2) settings里面设置kingadmin静态文件和templates路径
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'statics'),
os.path.join(BASE_DIR, 'kingadmin/statics'),
)
(4)PerfectCRM/url.py添加路由分发
urlpatterns = [
url(r'^kingadmin/', include('kingadmin.urls')),
]
(5)kingamdin/urls.py
# kingadmin/urls.py from django.conf.urls import url from kingadmin import views urlpatterns = [
url(r'^login/', views.acc_login,name='login'),
url(r'^logout/', views.acc_logout,name='logout'),
]
(6)kingamdin/views.py
登录界面也单独创建
# kingadmin/views.py from django.shortcuts import render,redirect
from django.contrib.auth import authenticate,login,logout def acc_login(request):
error_msg = ''
if request.method == 'POST':
username = request.POST.get('username',None)
password = request.POST.get('password',None)
#user是一个对象
#验证
user = authenticate(username=username,password=password)
if user:
#登录(已生成session)
login(request, user)
#如果有next值就获取next值,没有就跳转到首页
return redirect(request.GET.get('next','/kingadmin/'))
else:
error_msg = '用户名或密码错误!' return render(request,'kingadmin/login.html',{'error_msg':error_msg}) def acc_logout(request):
logout(request)
return redirect("/login/")
(7)kingamdin/urls.py
添加登录后跳转到“app_index.html”页面
urlpatterns = [
url(r'^$', views.app_index,name='app_index'),
url(r'^login/', views.acc_login,name='login'),
url(r'^logout/', views.acc_logout,name='logout'),
]
(8)kingadmin/views.py
def app_index(request):
return render(request,'kingadmin/app_index.html')
(9)kingadmin/app_index.html
kingadmin/index.html中添加block right-content-container
app_index.html
{#templates/kingadmin/app_index.html#} {% extends 'kingadmin/index.html' %} {% block right-content-container %}
<h2 class="page-header">APPS</h2>
{% endblock %}
4.2.kingadmin自动发现及注册功能开发
想让app_index.html页面像后台一样显示所有注册的app以及下面的表名
(1)kingadmin/app_setup.py
# kingadmin/app_setup.py from django import conf def kingadmin_auto_discover():
for app_name in conf.settings.INSTALLED_APPS:
try:
#去每个app下面执行kingadmin.py文件
mod = __import__('%s.kingadmin'%app_name)
#打印每个app已注册的model名字
print(mod.kingadmin)
except ImportError:
pass
(2)crm/kingadmin.py
# crm/kingadmin.py from kingadmin.sites import site
from crm import models print('crm kingadmin....') #注册model
class CustomerAdmin(object):
list_display = ['name','source','contact_type','contact','consultant','consult_content','status','date']
list_filter = ['source','consultant','status','date']
search_fields = ['contact','consultant__name'] site.register(models.CustomerInfo,CustomerAdmin)
(3)student/kingadmin.py
创建app student
student/models.py
# student/models.py from django.db import models class Test(models.Model):
name = models.CharField(max_length=64)
student/kingadmin.py
# student/kingadmin.py from student import models
from kingadmin.sites import site print('student kingadmin.....') #注册model
class TestAdmin(object):
list_display = ['name'] site.register(models.Test,TestAdmin)
(4)kingadmin/views.py
# kingadmin/views.py from kingadmin import app_setup
#程序一启动就自动执行
app_setup.kingadmin_auto_discover()
说明:
程序一启动,会执行每个app下面的kingadmin.py,注册全局的字典
from django import conf
conf.settings.INSTALL_APPS
动态获取settings里面所有添加的app名字
运行程序
(5)返回全局字典
我们想要的字典格式如下:
修改sites.py
# kingadmin/sites.py class AdminSite(object):
def __init__(self):
self.enable_admins = {} #两个参数,一个表名,一个自定义的admin类
def register(self,model_class,admin_class=None):
'''注册admin表''' # print('register',model_class,admin_class)
#获取app名字
app_name = model_class._meta.app_label
#获取表名
model_name = model_class._meta.model_name if app_name not in self.enable_admins:
self.enable_admins[app_name] = {}
self.enable_admins[app_name][model_name] = admin_class #实例化,就可以调用register方法
site = AdminSite()
kingamdin/views.py中打印看看
from kingadmin import app_setup
#程序已启动就自动执行
app_setup.kingadmin_auto_discover() from kingadmin.sites import site
print('site',site.enable_admins)
运行程序
(6)前端页面显示
kingamdin/views.py
def app_index(request): return render(request,'kingadmin/app_index.html',{'site':site})
kingadmin/templates/app_index.html
{#templates/kingadmin/app_index.html#} {% extends 'kingadmin/index.html' %} {% block right-content-container %}
<h2 class="page-header">APPS</h2> <div>
{% for app_name,app_tables in site.enable_admins.items %}
{{ app_name }}{{ app_tables }} {% endfor %} </div> {% endblock %}
4.3.kingadmin model obj list页面开发
把前端页面做成表格的格式,跟admin后台显示一样
bootstrap table: https://v3.bootcss.com/css/#tables
(1)kingadmin/app_index.html
{#templates/kingadmin/app_index.html#} {% extends 'kingadmin/index.html' %} {% block right-content-container %}
<h2 class="page-header">APPS</h2> <div>
{% for app_name,app_tables in site.enable_admins.items %}
<table class="table table-striped">
<thead>
<tr>
<th>{{ app_name }}</th>
</tr>
</thead>
<tbody>
{% for model_name in app_tables %}
<tr>
<td><a href="{% url 'table_obj_list' app_name model_name %}">{{ model_name }}</a></td>
<td>ADD</td>
<td>Change</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %} </div> {% endblock %}
(2)crm/kingadmin.py注册三个model
#注册model
class CustomerAdmin(object):
list_display = ['name','source','contact_type','contact','consultant','consult_content','status','date']
list_filter = ['source','consultant','status','date']
search_fields = ['contact','consultant__name'] site.register(models.CustomerInfo,CustomerAdmin)
site.register(models.Role)
site.register(models.Menus)
site.register(models.UserProfile)
(3)kingadmin/url.py
urlpatterns = [
url(r'^(\w+)/(\w+)/$', views.table_obj_list,name='table_obj_list'),
]
(4)kingadmin/sites.py
class AdminSite(object):
.
.
.
def register(self,model_class,admin_class=None):
.
.
.
#获取app名字
app_name = model_class._meta.app_label
#获取表名
model_name = model_class._meta.model_name
#把model_class赋值给了admin_class,然后在视图中可以通过admin_class找到对应的model类(表名字)
admin_class.model = model_class
.
.
.
此时运行发现会报错
是因为我们在注册model的时候,有的写了自定义的model类,有的没写,而我们都统一的赋值,导致那些没写自定义model类(空的)赋值的时候就会报NoneType错误
django自带的自定义admin类的写法继承了ModelAdmin,那注册的时候为什么有的没写自定义admin类没有报错呢?
是因为继承的ModelAdmin帮我们写了(里面其实都定义为空了),我们模仿django admin的写法,也写个父类。
(5)kingadmin/admin_base.py
新建个admin_base.py,写个父类
# kingadmin/admin_base.py class BaseKingAdmin(object): pass
(6)crm/kingadmin.py
# crm/kingadmin.py from kingadmin.sites import site
from crm import models
from kingadmin.admin_base import BaseKingAdmin # print('crm kingadmin....') #注册model
class CustomerAdmin(BaseKingAdmin):
list_display = ['name','source','contact_type','contact','consultant','consult_content','status','date']
list_filter = ['source','consultant','status','date']
search_fields = ['contact','consultant__name'] site.register(models.CustomerInfo,CustomerAdmin)
site.register(models.Role)
site.register(models.Menus)
site.register(models.UserProfile)
crm/kingadmin.py
继承BaseKingAdmin
(7)kingadmin/sites.py
# kingadmin/sites.py
from kingadmin.admin_base import BaseKingAdmin class AdminSite(object):
def __init__(self):
self.enable_admins = {} #两个参数,一个表名,一个自定义的admin类
def register(self,model_class,admin_class=BaseKingAdmin):
'''注册admin表''' # print('register',model_class,admin_class)
#获取app名字
app_name = model_class._meta.app_label
#获取表名
model_name = model_class._meta.model_name
#把model_class赋值给了admin_class,然后在视图中可以通过admin_class找到对应的model类(表名字)
admin_class.model = model_class
if app_name not in self.enable_admins:
self.enable_admins[app_name] = {}
self.enable_admins[app_name][model_name] = admin_class #实例化,就可以调用register方法
site = AdminSite()
kingadmin/sites.py
现在运行程序,就正常了,访问:http://127.0.0.1:8000/kingadmin/
(8)取出model里面的值
kingadmin/views.py
@login_required
def table_obj_list(request, app_name, model_name):
'''取出指定model里的数据返回给前端'''
#拿到admin_class后,通过它找到拿到model
admin_class = site.enable_admins[app_name][model_name]
querysets = admin_class.model.objects.all() return render(request, 'kingadmin/table_obj_list.html',{'querysets':querysets})
(9)templates/kingadmin/table_obj_list.html
{#kingadmin/templates/kingadmin/table_obj_list.html#} {% extends 'kingadmin/index.html' %} {% block right-content-container %}
<h2 class="page-header">app</h2> <div>
{{ querysets }}
<table class="table table-striped">
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody> </tbody>
</table>
</div> {% endblock %}
现在拿到的是一个对象,但是有个问题就是:没注册三个model里面得到值是一样
因为没注册的三个mdoel都共享同一个BaseKingAdmin内存对象(三个model内存地址一样),我们只需要实例化就可以了(实例化后就都有单独的内存空间了)
修改kingadmin/sites.py
# kingadmin/sites.py
from kingadmin.admin_base import BaseKingAdmin class AdminSite(object):
def __init__(self):
self.enable_admins = {} #两个参数,一个表名,一个自定义的admin类
def register(self,model_class,admin_class=None):
'''注册admin表''' # print('register',model_class,admin_class)
#获取app名字
app_name = model_class._meta.app_label
#获取表名
model_name = model_class._meta.model_name
#把model_class赋值给了admin_class,然后在视图中可以通过admin_class找到对应的model类(表名字)
if not admin_class:
# 实例化,如果没写注册的类,就用BaseKingAdmin
admin_class = BaseKingAdmin()
else:
#如果写了注册的类,就实例化自己
admin_class = admin_class()
admin_class.model = model_class
if app_name not in self.enable_admins:
self.enable_admins[app_name] = {}
self.enable_admins[app_name][model_name] = admin_class #实例化,就可以调用register方法
site = AdminSite()
现在就可以取出对应model的数据了
CRM客户关系管理系统(三)的更多相关文章
- Django CRM客户关系管理系统
CRM需求分析 随着信息化时代带来的科技创新,CRM客户关系管理系统带来的效益在已经成为很多企业提高竞争优势的一分部,CRM客户关系管理系统将企业管理和客户关系管理集成到统一的平台,其系统功能主要体现 ...
- CRM客户关系管理系统-需求概设和详设
大概设计 大概设计就是对需求进行一个整体性分析,把需要实现的功能都列出来,对于客户关系管理系统,我们需要从角色出发,从而确定有哪些需求,最好是画个思维导图 首先我们是为培训学校这么一个场景来开发的,所 ...
- CRM 客户关系管理系统
CRM(Customer Relationship Manager)客户关系管理系统 企业为提高核心竞争力,利用相应的信息技术以及互联网技术协调企业与顾客间在销售.营销和服务上的交互,从而提升其管理方 ...
- CRM客户关系管理系统 北京易信软科信息技术有限公司
北京易信软科信息技术有限公司 推出大型erp系统,库存管理系统,客户关系管理系统,车辆登记管理系统,员工管理系统,采购管理系统,销售管理系统,为您的企业提供最优质的产品服务 北京易信软科您可信赖的北京 ...
- CRM客户关系管理系统(一)
第一章.CRM介绍和开发流程 1.1.CRM简介 客户关系管理(CRM) 客户关系管理(customer relationship management)的定义是:企业为提高核心竞争力,利用相应的信息 ...
- Django项目:CRM(客户关系管理系统)--84--74PerfectCRM实现CRM权限和权限组限制访问URL
#models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...
- Django项目:CRM(客户关系管理系统)--85--75PerfectCRM实现CRM扩展权限
# sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...
- Django项目:CRM(客户关系管理系统)--70--60PerfectCRM实现CRM学生上课记录
#urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...
- Django项目:CRM(客户关系管理系统)--69--59PerfectCRM实现king_admin行内编辑
#base_admin.py # ————————24PerfectCRM实现King_admin自定义操作数据———————— from django.shortcuts import render ...
随机推荐
- java专业术语
java的(PO,VO,TO,BO,DAO,POJO)解释 PO(persistant object) 持久对象 在o/r映射的时候出现的概念,如果没有o/r映射,没有这个概念存在了.通常对应数据模型 ...
- 论文泛读·Adversarial Learning for Neural Dialogue Generation
原文翻译 导读 这篇文章的主要工作在于应用了对抗训练(adversarial training)的思路来解决开放式对话生成(open-domain dialogue generation)这样一个无监 ...
- Properties文件中文属性读取是乱码问题
项目当中遇到了需要从Properties文件中读取配置属性的需求,本来是存储的中文转码后的属性,但是考虑到后期更改问题就变成java代码中进行转码,代码如下: Properties pros = ne ...
- IOS 中openGL使用教程4(openGL ES 入门篇 | 离屏渲染)
通常情况下,我们使用openGL将渲染好的图片绘制到屏幕上,但有时候我们不想显示处理结果,这时候就需要使用离屏渲染了. 正常情况下,我们将屏幕,也就是一个CAEAGLLayer对象作为渲染目标,离屏渲 ...
- spring 依赖注入时,什么时候会创建代理类
问题来源 以前一直有个疑惑,为什么我创建的controller中注入的service类有时候是代理类,有时候是普通javabean,当时能力不够,现在已经有了点经验就大胆跟了跟源码,看看到底咋回事. ...
- 【转载】Ubuntu 12.04 LTS 中文输入法的安装
原文地址 : http://www.cnblogs.com/zhj5chengfeng/archive/2013/06/23/3150620.html 我装的是英文版的 Ubuntu12.04,如果 ...
- linux samba服务配置
1.下载 wget+rpm或yum install 2.配置/etc/samba/smb.conf cat smb.conf | grep setsebool 执行终端打印出来的字符串 setsebo ...
- Jenkins + Gradle + pgyer + Android自动发布
Jenkins配置与必要的环境配置 一:Jenkins服务端(Linux系统为例说明): 1.jdk安装与配置 2.SDK安装与配置 3.安装配置对应的gradle版本(建议gradle版本在4.1版 ...
- 前端页面间传值之cookie传值和url传值
大家好,我是小C: 我们在做一些网站需要传值交互,最近我就遇到了这问题,如果用H5的本地存储,IE8以下是不能支持的,但是官方说到IE8及以上就支持,但是某些版本还是存在问题.所以我们来看看下面两种方 ...
- [NOI2005]寿司晚宴
题目描述 为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴.小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿司,编号1,2,3,⋯,n-1 ...