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(r'customers/',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

以上步驟的展示效果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM