Python CRM项目二

一.准备工作

如果没有配置基本的项目,请参考 http://www.cnblogs.com/luhuajun/p/7771196.html

当我们配置完成后首先准备我们的app

创建2个app分别对应学生,重写的Admin模板

1 python manager.py startapp student  #学生视图
2 python manager.py startapp king_admin #king_admin视图

配置每个app的url映射

1.主app

1 #将每个模块的urls.py引入
2 urlpatterns = [
3     url(r‘^admin/‘, admin.site.urls),
4     url(r‘^crm/‘,include(‘crm.urls‘)),
5     url(r‘^student/‘,include(‘student.urls‘)),
6     url(r‘^king_admin/‘,include(‘king_admin.urls‘)),
7 ]

2.crm

1 urlpatterns = [
2     url(r‘^$‘,views.index,name=‘sales_index‘),#销售首页
3     url(r‘customers/‘,views.customer_list,name=‘customer_list‘),#客户库
4 ]

3.student

1 urlpatterns = [
2     #学生首页
3     url(r‘^$‘,views.index,name=‘stu_index‘),
4 ]

4.king_admin

1 urlpatterns = [
2     #表首页
3     url(r‘^$‘,views.index,name=‘table_index‘),
4 ]

配置每个url的视图

1.crm

1 def index(request):
2     #返回销售首页
3     return render(request,‘index.html‘,name=‘sales_index‘)
4
5
6 def customer_list(request):
7     #返回客户库首页
8     return render(request,‘sales/customers.html‘)

2.student

1 def index(request):
2     #返回学生首页
3     return render(request,‘student/index.html‘)

3.king_admin

1 def index(request):
2     #返回表格管理页面
3     return render(request, ‘king_admin/table_index.html‘,{‘table_list‘:king_admin.enabled_admins})

配置前端页面

模板使用:http://v3.bootcss.com/examples/dashboard/

将上面的模板下载,将css,js,文件按一下的层级结构归类

下载的html文件进行分解,分解为base.html和index.html

base.html存放css文件和js文件

index.html继承base.html然后在此基础上进行定制

base.html

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3   <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
 8     <meta name="description" content="">
 9     <meta name="author" content="">
10
11
12     <title>oldboy CRM</title>
13
14     <!-- Bootstrap core CSS -->
15     <link href="/static/css/bootstrap.min.css" rel="stylesheet">
16
17     <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
18     <link href="/static/css/dashboard.css" rel="stylesheet">
19
20     <!-- Custom styles for this template -->
21     <link href="/static/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
22     <link href="/static/plugins/dropzone/dropzone.css" rel="stylesheet">
23
24     {% block css %}{% endblock %}
25
26
27   </head>
28
29   {% block body %}{% endblock %}
30
31
32     <script src="/static/js/jquery.min.js"></script>
33     <script src="/static/js/bootstrap.min.js"></script>
34     <script src="/static/js/holder.min.js"></script>
35     <script src="/static/js/ie10-viewport-bug-workaround.js"></script>
36     <script src="/static/plugins/dropzone/dropzone.js"></script>
37   {% block bottom-js %}{% endblock %}
38 </html>

index.html

 1 {% extends ‘base.html‘ %}
 2 {% block body %}
 3 <body>
 4     <nav class="navbar navbar-inverse navbar-fixed-top">
 5       <div class="container-fluid">
 6         <div class="navbar-header">
 7           <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
 8             <span class="sr-only">Toggle navigation</span>
 9             <span class="icon-bar"></span>
10             <span class="icon-bar"></span>
11             <span class="icon-bar"></span>
12           </button>
13           <a class="navbar-brand" href="#">My CRM</a>
14         </div>
15         <div id="navbar" class="navbar-collapse collapse">
16           <ul class="nav navbar-nav navbar-right">
17
18
19             <li class="dropdown">
20                 <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{ request.user }}</a>
21                 <ul class="dropdown-menu" role="menu">
22 {#                    <li><a href="{% url ‘acc_logout‘ %}">注销</a></li>#}
23                 </ul>
24             </li>
25           </ul>
26
27         </div>
28       </div>
29     </nav>
30
31     <div class="container-fluid">
32       <div class="row">
33         <div class="col-sm-3 col-md-2 sidebar">
34           <ul class="nav nav-sidebar">
35 {#            {% for role in request.user.roles.all %}#}
36 {#                {% for menu in role.menus.all %}#}
37 {#                    <li><a href="{% if menu.url_type == 0 %}{% url menu.url_name %}{% else %}{{   menu.url_name }}{% endif %}">{{ menu.name }}</a></li>#}
38 {#                {% endfor %}#}
39 {#            {% endfor %}#}
40               {% for role in request.user.userprofile.roles.all %}
41                 {% for menu in role.menus.all %}
42                     <li><a href="{% url menu.url_name %}">{{ menu.name }}</a></li>
43                 {% endfor %}
44               {% endfor %}
45           </ul>
46
47         </div>
48         <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
49            {% block page-content %}
50             <h1 class="page-header">Dashboard</h1>
51             <div class="row placeholders">
52             <div class="col-xs-6 col-sm-3 placeholder">
53               <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
54               <h4>Label</h4>
55               <span class="text-muted">Something else</span>
56             </div>
57             <div class="col-xs-6 col-sm-3 placeholder">
58               <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
59               <h4>Label</h4>
60               <span class="text-muted">Something else</span>
61             </div>
62             <div class="col-xs-6 col-sm-3 placeholder">
63               <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
64               <h4>Label</h4>
65               <span class="text-muted">Something else</span>
66             </div>
67             <div class="col-xs-6 col-sm-3 placeholder">
68               <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
69               <h4>Label</h4>
70               <span class="text-muted">Something else</span>
71             </div>
72           </div>
73
74
75             <h2 class="sub-header">Section title</h2>
76             {% endblock %}
77         </div>
78       </div>
79
80     </div>
81   </body>
82 {% endblock %}

然后在template下创个各个app名称的文件夹来存放不同app的页面,目录结构如下

然后启动项目,看看每个url是否可以正常访问

准备数据

在插入数据之前,由于本项目要是用动态菜单,所以还要创建一张菜单表和角色表进行关联

 1 class Menu(models.Model):
 2     ‘‘‘菜单表‘‘‘
 3     name = models.CharField(max_length=32)
 4     url_name = models.CharField(max_length=64,unique=True)
 5
 6     def __str__(self):
 7         return self.name
 8     class Meta:
 9         verbose_name_plural = ‘菜单‘
10
11
12 class Role(models.Model):
13     ‘‘‘角色表‘‘‘
14     name = models.CharField(max_length=64,unique=True)
15     #新增菜单信息
16     menus = models.ManyToManyField(‘Menu‘,blank=True)
17     def __str__(self):
18         return self.name
19
20     class Meta:
21         verbose_name_plural = ‘角色‘

同步数据库,启动项目,进入admin后台管理

在一些表中插入数据

首先插入tag表

1 INSERT INTO prefect_crm.crm_tag (name) VALUES (‘土豪‘);
2 INSERT INTO prefect_crm.crm_tag (name) VALUES (‘屌丝‘);
3 INSERT INTO prefect_crm.crm_tag (name) VALUES (‘无基础‘);
4 INSERT INTO prefect_crm.crm_tag (name) VALUES (‘有基础‘);
5 INSERT INTO prefect_crm.crm_tag (name) VALUES (‘有工作经验‘);
6 INSERT INTO prefect_crm.crm_tag (name) VALUES (‘没文化‘);
7 INSERT INTO prefect_crm.crm_tag (name) VALUES (‘没有工作经验‘);
8 INSERT INTO prefect_crm.crm_tag (name) VALUES (‘转行‘);

菜单表

1 INSERT INTO prefect_crm.crm_menu (name, url_name) VALUES (‘销售首页‘, ‘sales_index‘);
2 INSERT INTO prefect_crm.crm_menu (name, url_name) VALUES (‘学生首页‘, ‘stu_index‘);
3 INSERT INTO prefect_crm.crm_menu (name, url_name) VALUES (‘客户库‘, ‘customer_list‘);

角色表

1 INSERT INTO prefect_crm.crm_role (name) VALUES (‘学生‘);
2 INSERT INTO prefect_crm.crm_role (name) VALUES (‘销售‘);

角色和菜单的关联表

1 INSERT INTO prefect_crm.crm_role_menus (role_id, menu_id) VALUES (1, 1);
2 INSERT INTO prefect_crm.crm_role_menus (role_id, menu_id) VALUES (1, 3);
3 INSERT INTO prefect_crm.crm_role_menus (role_id, menu_id) VALUES (2, 2);

用户表

1 INSERT INTO prefect_crm.crm_userprofile (name, user_id) VALUES (‘Alex Li‘, 1);
2 INSERT INTO prefect_crm.crm_userprofile (name, user_id) VALUES (‘Jack‘, 2);

用户角色关联表

1 INSERT INTO prefect_crm.crm_userprofile_roles (userprofile_id, role_id) VALUES (1, 1);
2 INSERT INTO prefect_crm.crm_userprofile_roles (userprofile_id, role_id) VALUES (2, 2);

课程表

1 INSERT INTO prefect_crm.crm_course (name, price, period, outline) VALUES (‘Python‘, 18900, 5, ‘1.python语法
2 2.python基础
3 3.前端
4 4.项目‘);

客户表

1 INSERT INTO prefect_crm.crm_customer (name, qq, qq_name, phone, source, referral_from, content, memo, status, date, consult_course_id, consultant_id) VALUES (‘大锤‘, ‘1234567890‘, ‘大锤‘, ‘1234567890‘, 1, ‘‘, ‘上课时间
2 上课地点
3 价格‘, ‘没有报名‘, ‘unregistered‘, ‘2017-10-17 01:48:53‘, 1, 1);
4 INSERT INTO prefect_crm.crm_customer (name, qq, qq_name, phone, source, referral_from, content, memo, status, date, consult_course_id, consultant_id) VALUES (‘小锤‘, ‘1234567891‘, ‘小锤‘, ‘1234567891‘, 2, ‘‘, ‘价格
5 地点
6 学习周期‘, ‘有点低能‘, ‘unregistered‘, ‘2017-10-17 01:49:49‘, 1, 1);
7 INSERT INTO prefect_crm.crm_customer (name, qq, qq_name, phone, source, referral_from, content, memo, status, date, consult_course_id, consultant_id) VALUES (‘小悦悦‘, ‘1234567892‘, ‘小悦悦‘, ‘1234567892‘, 4, ‘‘, ‘价格
8 授课方式
9 是否有美女‘, ‘有强烈的学习意向‘, ‘signed‘, ‘2017-10-17 01:52:12‘, 1, 2);

客户和标签的关系表

1 INSERT INTO prefect_crm.crm_customer_tags (customer_id, tag_id) VALUES (1, 4);
2 INSERT INTO prefect_crm.crm_customer_tags (customer_id, tag_id) VALUES (1, 7);
3 INSERT INTO prefect_crm.crm_customer_tags (customer_id, tag_id) VALUES (2, 2);
4 INSERT INTO prefect_crm.crm_customer_tags (customer_id, tag_id) VALUES (2, 5);
5 INSERT INTO prefect_crm.crm_customer_tags (customer_id, tag_id) VALUES (3, 2);
6 INSERT INTO prefect_crm.crm_customer_tags (customer_id, tag_id) VALUES (3, 8);

在此列出这些数据表,但是我们在Django admin自带的后台管理中,不需要插入中间表,系统会自动在中间表中关联,此处只是说明表关系

二.动态菜单的展示

在配置完数据之后,首先在页面的右上角展示登录的用户名,在左侧菜单根据不同的用户展示不同的明细

因为userprofile中关联了Django自带的User,所以展示用户名只需要一行代码

在index.html中找到相应的行,替换即可

1 <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{ request.user }}</a>

因为在userprofile中已经关联了role,而role关联了菜单所以在前端可以直接循环userprofile来获取菜单

在index.html中找到相应的行,替换即可

1 {% for role in request.user.userprofile.roles.all %}
2                 {% for menu in role.menus.all %}
3                     <li><a href="{% url menu.url_name %}">{{ menu.name }}</a></li>
4                 {% endfor %}
5               {% endfor %}

这样动态菜单就设置完成

三.king_admin动态绑定models

因为我们要重写Django Admin的功能,所以首先分析Admin展示的数据结构

第一级是App

第二级是models

第三级是字段

所以数据结构是

{app_name:{model_name:model_object,model_name1:model_object1,model_name2:model_object2....},}

这样的分层结构来封装数据,并返回给前端展示

根据类自动获取关联的表名和app名称

过程

1 #1.进入python交互环境
2 python manage.py shell
3
4 #2.找到app名称
5 from crm import models
6 models.UserProfile._meta.app_config
7
8 #3.找到表名
9 models.UserProfile._meta.app_label

核心代码:

1 def register(model_class,admin_class=None):
2     #如果不存再app,就新建一个字典,并且绑定admin_class和mode_class
3     if model_class._meta.app_label not in enabled_admins:
4         enabled_admins[model_class._meta.app_label] = {}
5     #绑定model对象和admin类,类似于admin的register方法
6     admin_class.model = model_class
7     #将字典的格式写成{app:{‘model_name‘:model_obj}}这种格式
8     enabled_admins[model_class._meta.app_label][model_class._meta.model_name] = admin_class

总体代码:

 1 from crm import models
 2 enabled_admins = {} #全局字典
 3
 4 class BaseAdmin(object):
 5     #基类
 6     list_display = []
 7     list_filter = []
 8
 9 #定制类
10 class CustomerFollowUpAdmin(BaseAdmin):
11     list_display = [‘customer‘, ‘consultant‘,‘date‘]
12
13 class CustomerAdmin(BaseAdmin):
14     list_display = [‘qq‘,‘name‘]
15     #model = model.Customer
16
17 #绑定model和定制类的方法
18 def register(model_class,admin_class=None):
19     if model_class._meta.app_label not in enabled_admins:
20         enabled_admins[model_class._meta.app_label] = {}
21     admin_class.model = model_class#绑定model对象和admin类
22     enabled_admins[model_class._meta.app_label][model_class._meta.model_name] = admin_class
23
24 #注册
25 register(models.Customer,CustomerAdmin)

 1 from crm import models
 2 enabled_admins = {} #全局字典
 3
 4 class BaseAdmin(object):
 5     #基类定义一些展示方法
 6     list_display = []
 7     list_filter = []
 8
 9 class CustomerFollowUpAdmin(BaseAdmin):
10     #自定义展示
11     list_display = [‘customer‘, ‘consultant‘,‘date‘]
12
13 class CustomerAdmin(BaseAdmin):
14     list_display = [‘qq‘,‘name‘]
15     #model = model.Customer
16
17
18 def register(model_class,admin_class=None):
19     if model_class._meta.app_label not in enabled_admins:
20         enabled_admins[model_class._meta.app_label] = {}
21     #绑定model对象和admin类
22     admin_class.model = model_class
23     enabled_admins[model_class._meta.app_label][model_class._meta.model_name] = admin_class
24
25 #注册
26 register(models.Customer,CustomerAdmin)
27 register(models.CustomerFollowUp,CustomerFollowUp

视图映射

1 from django.shortcuts import render
2 from king_admin import king_admin
3 # Create your views here.
4 def index(request):
5
6     return render(request, ‘king_admin/table_index.html‘,{‘table_list‘:king_admin.enabled_admins})

页面

 1 {% extends ‘base.html‘ %}
 2 {% block body %}
 3 <body>
 4     <nav class="navbar navbar-inverse navbar-fixed-top">
 5       <div class="container-fluid">
 6         <div class="navbar-header">
 7           <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
 8             <span class="sr-only">Toggle navigation</span>
 9             <span class="icon-bar"></span>
10             <span class="icon-bar"></span>
11             <span class="icon-bar"></span>
12           </button>
13           <a class="navbar-brand" href="#">My CRM</a>
14         </div>
15         <div id="navbar" class="navbar-collapse collapse">
16           <ul class="nav navbar-nav navbar-right">
17
18
19             <li class="dropdown">
20                 <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{ request.user }}</a>
21                 <ul class="dropdown-menu" role="menu">
22 {#                    <li><a href="{% url ‘acc_logout‘ %}">注销</a></li>#}
23                 </ul>
24             </li>
25           </ul>
26
27         </div>
28       </div>
29     </nav>
30
31     <div class="container" style="margin-top:50px;">
32         <div class="row">
33             <div class="panel panel-info">
34               <div class="panel-heading">
35                 <h3 class="panel-title">Panel title</h3>
36               </div>
37               <div class="panel-body">
38                 {% for app_name,app_tables in table_list.items %}
39                 <table class="table table-hover">
40                    <thead>
41                     <tr>
42                        <th>{{ app_name }}</th>
43                     </tr>
44                    </thead>
45
46                    <tbody>
47                    {% for table_name,admin in app_tables.items %}
48                     <tr>
49                         <td>{{ table_name }}</td>
50                         <td>add</td>
51                         <td>change</td>
52                     </tr>
53                     {% endfor %}
54                    </tbody>
55
56                 </table>
57                {% endfor %}
58               </div>
59             </div>
60         </div>
61     </div>
62
63
64 </body>
65 {% endblock %}

以上步骤的展示效果

时间: 2024-10-14 04:25:12

Python CRM项目二的相关文章

Python CRM项目三

1.分页: 分页使用Django内置的分页模块来实现 官方的分页案例 1 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 2 from django.shortcuts import render 3 #后端 4 def listing(request): 5 contact_list = Contacts.objects.all() 6 paginator = Paginator(contact_

Python CRM项目四

实现Django Admin的多对多的复选框效果 效果:左边显示的是未选中的字段,右边显示的是已选中的字段,两边点击的标签可以互相更换 首先在king_admin.py中增加filter_horizontal字段 1 class CustomerAdmin(BaseAdmin): 2 list_display = ['qq','name','source','consultant','consult_course','date','status'] 3 list_filters = ['sour

crm 系统项目(二) admin 后台操作表格

crm 系统项目(二) admin 后台操作表格 1. app下创建 templates  运行的时候 先找全局的templates——> 按照app的注册顺序找templates中的文件 2. app下在创建一个urls.py include() 3. 创建超级用户 python manage.py createsuperuser 邮箱可以忽略,密码默认为8位 4. 在admin中注册model from django.contrib import admin from crm import

超实用python小项目--基于python的手机通讯录二维码生成网站--1、项目介绍和开发环境

这个项目是我做完整的第一个python web项目,对于新手来说,这个项目绝对是一个特别好的练手项目. 起名还是困难,但是自己确实比较烦输入这么长的名字(手机通讯录二维码生成网站)去定义这个网站,所以还是给这个项目起个名字吧,叫什么呢?就叫 "鹅日通讯录"吧(Earth address list). --------------------------------------------------------------------------------------------我是

**crm项目部署**

crm项目部署 1.nginx + uwsgi + django+虚拟环境+supervisor+mysql 2.django的启动方式 python3 manage.py runserver 为什么不能在生产环境用?4 django只是一个web逻辑框架,它通过python3 manage.py runserver 命令启动socket服务端 是借助python内置的wsgi框架,wsgiref框架实现的 他是一个单机模块,单进程模块,性能很低 因此在线上需要借助通过c语言编写的uwsgi这个

Python爬虫进阶二之PySpider框架安装配置

关于 首先,在此附上项目的地址,以及官方文档 PySpider 官方文档 安装 1. pip 首先确保你已经安装了pip,若没有安装,请参照 pip安装 2. phantomjs PhantomJS 是一个基于 WebKit 的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速.原生支持各种Web标准:DOM 处理.CSS 选择器.JSON.Canvas 和 SVG. PhantomJS 可以用于页面自动化.网络监测.网页截屏以及无界面测试等. 安装 以上附有官方安

Python基础之二:数据类型

四.Python数据类型 数字 字符串 列表 元祖 字典 1.数字类型 整型 表示范围:-2147483648到2147483647,超过该范围的会被当作长整型 示例:num=123 type(num)-返回<type 'int'>,用来测试变量的类型 长整型 表示范围:任意大整数,后跟L或l与整型区别 示例:num=1l type(num)-返回<type 'long'> 浮点型 示例:num=12.0 type(num) -返回<type'float'> 复数型 示

python学习(二)百度爬虫0.1

参照着网上的爬虫案例(点我),先做了一个demo,基本的爬虫项目创建,以及数据抽取,数据分析,数据保存等等过程基本上有所掌握. 我的需求是需要检索指定的百度贴吧,根据指定的关键字库,搜索出含有关键字的链接,并抽取出来,用于后续告警. 因此,基于需求,分如下步骤: 第一:基于Scrapy创建爬虫项目: 第二:新建TieBaSpider爬虫: 第三:新建外部关键字库dictionary.txt文件,贴吧地址配置url.txt文件: 第一步参考晚上案例. 从第二步开始,编写爬虫,同时创建实例对象以及创

Python爬虫利器二之Beautiful Soup的用法

上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫Beautiful Soup,有了它我们可以很方便地提取出HTML或XML标签中的内容,实在是方便,这一节就让我们一起来感受一下Beautiful Soup的强大吧. 1. Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官