Python CRM项目二

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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视图
View Code

配置每个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 ]
View Code

2.crm

技术分享
1 urlpatterns = [
2     url(r^$,views.index,name=sales_index),#销售首页
3     url(rcustomers/,views.customer_list,name=customer_list),#客户库
4 ]
View Code

3.student

技术分享
1 urlpatterns = [
2     #学生首页   
3     url(r^$,views.index,name=stu_index),
4 ]
View Code

4.king_admin

技术分享
1 urlpatterns = [
2     #表首页
3     url(r^$,views.index,name=table_index),
4 ]
View Code

配置每个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)
View Code

2.student

技术分享
1 def index(request):
2     #返回学生首页
3     return render(request,student/index.html)
View Code

3.king_admin

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

配置前端页面

模板使用: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>
View Code

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 %}
View Code

然后在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 = ‘角色‘
View Code

同步数据库,启动项目,进入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 (转行);
View Code

菜单表

技术分享
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);
View Code

角色表

技术分享
1 INSERT INTO prefect_crm.crm_role (name) VALUES (学生);
2 INSERT INTO prefect_crm.crm_role (name) VALUES (销售);
View Code

角色和菜单的关联表

技术分享
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);
View Code

用户表

技术分享
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);
View Code

用户角色关联表

技术分享
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);
View Code

课程表

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

客户表

技术分享
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);
View Code

客户和标签的关系表

技术分享
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);
View Code

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

二.动态菜单的展示

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

技术分享

 

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

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

技术分享
1 <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{ request.user }}</a>
View Code

因为在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 %}
View Code

这样动态菜单就设置完成

三.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
View Code

核心代码:

技术分享
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
View Code

总体代码:

技术分享
 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)
View Code

 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})
View Code

页面

技术分享
 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 %}
View Code

以上步骤的展示效果

技术分享

 

以上是关于Python CRM项目二的主要内容,如果未能解决你的问题,请参考以下文章

Python CRM项目三

Python CRM项目二

Python CRM项目四

**crm项目部署**

python(CRM)

如何通过单击适配器类中代码的项目中的删除按钮来删除列表视图中的项目后重新加载片段?