CRM项目(二)

CRM项目开发(二)

文章目录
  1. 1. 构造Home首页
    1. 1.1. 创建应用
    2. 1.2. 原生admin首页分析
    3. 1.3. 构造应用路由
    4. 1.4. 构建前端模板
      1. 1.4.1. 创建静态文件目录
      2. 1.4.2. 构造底层基础母板
      3. 1.4.3. 创建项目所需主页
    5. 1.5. 编写视图函数
  2. 2. 构造admin注册功能
    1. 2.1. 原生admin注册功能分析
      1. 2.1.1. 仿写注册功能
    2. 2.2. 进行注册
  3. 3. 添加项目名称和字段
    1. 3.1. 查询项目名称
    2. 3.2. 查询字段名称
    3. 3.3. 模板中添加名称

CRM系统是一个相对较复杂的软件,其中重构admin是最为繁琐的过程,这个解决掉其他都是松松的!路漫漫其修远兮,重写admin也是一个漫长的过程。

接下来是重写admin的过程:

 

 

 

 

 

 

 

 

构造Home首页

创建应用

将新的admin作为一个应用,便于扩展和移植。根目录下,创建应用,并命名为:king_admin(根据自己的喜好)

————》:django-Admin startapp king_admin

原生admin首页分析

Django自带的后台中,首页显示的是项目名称和数据库表中的字段名称,并显示添加和修改功能。(其中,数据库中绑定了url的映射关系,添加对应的映射名称即可)

这里不显示,原生后台的UsersGroups内容,将在后面的权限管理中独立出来!

构造应用路由

from django.conf.urls import url
from king_admin import views
urlpatterns = [ url(r'^$', views.index, name='table_index'), #name是对应数据库中的映射关系 ]

构建前端模板

创建静态文件目录

使用Bootsrap框架,项目中创建statics目录并在settings.py中添加对应路径:

STATIC_URL = '/static/'
#添加以下内容
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'statics'),
)
构造底层基础母板

templates目录下添加base.html作为所有可继承模板的母板,主要是用来引入样式CSSJS

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta 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="">
    <title>Django Admin</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>
  <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='{% url 'crm_index' %}'>PerfectCRM</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>
      {% block body-content %}{% endblock %}
  </body>
 <!-- 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>
创建项目所需主页

为了更好的扩展和区分,在templates目录下单独建立对应项目的存储模板文件的目录king_admin,然后创建table_index.html文件。

table_index.html文件内容如下:

{% extends 'base.html' %}   #继承母板
{% block body-content %} #继承块内容
    <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">King_Admin</h3>
              </div>
              <div class="panel-body">
                     <table class="table table-hover">
                        <thead>
                            <tr>
                                <th></th>
                            </tr>
                        </thead>
                        <tbody>
                                <tr>
                                    <td>显示字段</td>
                                    <td>添加</td>
                                    <td>修改</td>
                                </tr>
                        </tbody>
                     </table>
              </div>
            </div>
        </div>
    {% endblock %}
    </div>
{% endblock %}

编写视图函数

from django.shortcuts import render
def index(request):
    return render(request, 'king_admin/table_index.html')

访问结果,如下图:

按钮修饰自己按照bootstrap耍吧

构造admin注册功能

前面我们先简单的编写了能够访问的首页,但是需要显示数据库的字段名称和项目名称,必须要有向admin注册的功能。

原生admin注册功能分析

在开始,我们访问原生的admin时,我们需要先注册数据库的表名及类的名称和自定义的类名称。这流程看起来简单,后台实现起来其实也是很简单的!

仿写注册功能

king_admin应用下面添加king_admin.py文件,并编写以下内容:


#创建基类 class BaseAdmin(object): list_display = [] list_filter = [] list_per_page = 2 #数据结构容器 enabled_admins = {} """ {项目名: {表名1: 自定义类1, 表名2: 自定义类2, }, } """ #构造数据结构--->通过models类和自定义类注册获取 def register(model_class, admin_class=None): if model_class._meta.app_label not in enabled_admins: #添加项目名称 enabled_admins.update({model_class._meta.app_label: {}}) #添加自定义类属性为models类 admin_class.model = model_class #通过表名获取到自定义类 enabled_admins[model_class._meta.app_label][model_class._meta.model_name] = admin_class

进行注册

from CRM import models
#创建基类
class BaseAdmin(object):
    list_display = []
    list_filter = []
    list_per_page = 2
#数据结构容器
enabled_admins = {}
"""
{项目名: {表名1: 自定义类1,
         表名2: 自定义类2,
        },
}
"""
#构造数据结构--->通过models类和自定义类注册获取
def register(model_class, admin_class=None):
    if model_class._meta.app_label not in enabled_admins:
        #添加项目名称
        enabled_admins.update({model_class._meta.app_label: {}})
    #添加自定义类属性为models类
    admin_class.model = model_class
    #通过表名获取到自定义类
    enabled_admins[model_class._meta.app_label][model_class._meta.model_name] = admin_class
#自定义类,显示特定字段
class CustomerAdmin(BaseAdmin):
    list_display = ['qq','name','source','consultant','consult_course','date','status']
    list_filters = ['source','consultant','consult_course','status']
    #model = models.Customer
class CustomerFollowUpAdmin(BaseAdmin):
    list_display = ('customer','consultant','date')
#进行注册,构造数据结构
register(models.Customer, CustomerAdmin)
register(models.CustomerFollowUp, CustomerFollowUpAdmin)

上面这样写在同一个文件中,是不是很别扭,为什么不将注册功能和注册行为分开呢??

其实,注册行为和功能的分开是很有必要的,方便功能的扩展和避免与行为的混淆,更利于架构的优化!

解决如下:

待解决。。。

添加项目名称和字段

添加的内容,我们需要使用到Djangoshell进行测试查询我们需要的方法、属性。

终端中,进入到shell

>>>python  manage.py  shell
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

查询项目名称

king_admin.py中自定义的enable_admins中遍历即可。

查询字段名称

查询字段名称,最先想到的是当我们操作数据库时,models中的最接近字段名称应该是类的名称也就是表名。因此,先查询表名下的属性和方法:

>>> from  CRM  import  models
>>> a = models.Customer
>>> >>> dir(a)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__modul
e__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slotnames__', '__str__', '__subclasshook__', '__weakref__', '_constructor_arg
s', '_db', '_get_queryset_methods', '_hints', '_insert', '_originating_model', '_queryset_class', '_set_creation_counter', '_update', 'aggregate', 'all', 'annotate', 'auto_created
', 'bulk_create', 'check', 'complex_filter', 'contribute_to_class', 'count', 'create', 'creation_counter', 'dates', 'datetimes', 'db', 'db_manager', 'deconstruct', 'defer', 'disti
nct', 'earliest', 'exclude', 'exists', 'extra', 'filter', 'first', 'from_queryset', 'get', 'get_or_create', 'get_queryset', 'in_bulk', 'iterator', 'last', 'latest', 'model', 'name
', 'none', 'only', 'order_by', 'prefetch_related', 'raw', 'reverse', 'select_for_update', 'select_related', 'update', 'update_or_create', 'use_in_migrations', 'using', 'values', '
values_list']

在上面会看到很多方法和属性,其中一个很是关键:_meta,是对改类的操作。继续:

>>> a._meta
<Options for Customer>
>>> dir(a._meta)
['FORWARD_PROPERTIES', 'REVERSE_PROPERTIES', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash_
_', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__we
akref__', '_expire_cache', '_forward_fields_map', '_get_fields', '_get_fields_cache', '_ordering_***', '_populate_directed_relation_graph', '_prepare', '_relation_tree', 'abstra
ct', 'add_field', 'add_manager', 'app_config', 'app_label', 'apps', 'auto_created', 'auto_field', 'base_manager', 'base_manager_name', 'can_migrate', 'concrete_fields', 'concrete_
model', 'contribute_to_class', 'db_table', 'db_tablespace', 'default_apps', 'default_manager', 'default_manager_name', 'default_permissions', 'default_related_name', 'fields', 'fi
elds_map', 'get_ancestor_link', 'get_base_chain', 'get_field', 'get_fields', 'get_latest_by', 'get_parent_list', 'has_auto_field', 'index_together', 'installed', 'label', 'label_l
ower', 'local_concrete_fields', 'local_fields', 'local_managers', 'local_many_to_many', 'managed', 'manager_inheritance_from_future', 'managers', 'managers_map', 'many_to_many', '
model', 'model_name', 'object_name', 'order_with_respect_to', 'ordering', 'original_attrs', 'parents', 'permissions', 'pk', 'private_fields', 'proxy', 'proxy_for_model', 'related_
fkey_lookups', 'related_objects', 'required_db_features', 'required_db_vendor', 'select_on_save', 'setup_pk', 'setup_proxy', 'swappable', 'swapped', 'unique_together', 'verbose_na
me', 'verbose_name_plural', 'verbose_name_raw', 'virtual_fields']

很显然,上面有我们所需要的:

>>> a._meta.verbose_name
'客户表'

模板中添加名称

既然,我们所要的数据都找到了来源,剩下的就是在模板中添加进行渲染了。

table_index.html中,添加内容如下(自行对比前面):

{% extends 'base.html' %}
{% load tags %}  #引入自定标签
{% block body-content %}
    <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">King_Admin</h3>
              </div>
              <div class="panel-body">
                  {{ table_list }}
                  {% for app_name, table_names in table_list.items %}
                     <table class="table table-hover">
                        <thead>
                            <tr>
                                <th>{{ app_name }}</th>
                            </tr>
                        </thead>
                        <tbody>
                            {% for table_name, admin in table_names.items %}
                                <tr>
                                    {#1.链接:url/应用名/表名,2. 显示中文表名--使用自定义标签进行处理#}
                                    <td>{% render_verbose_name admin %}</td>
                                    <td>添加</td>
                                    <td>修改</td>
                                </tr>
                            {% endfor %}
                        </tbody>
                     </table>
                  {% endfor %}
              </div>
            </div>
        </div>
    {% endblock %}
    </div>
{% endblock %}

文件中,需要使用到自定义标签的功能,具体的使用请看官网或后边会有自定义标签!

 模板标签文件的内容如下:

from  django  import template
register = template.Library()
#------------------------显示表名称-->中文---------------------------
@register.simple_tag
def render_verbose_name(admin_class):
    return admin_class.model._meta.verbose_name

现实如下:

 

posted @ 2017-01-16 16:40  runnering  阅读(195)  评论(0)    收藏  举报