您现在的位置是: 网站首页 >Django >DjangoCRM客户关系管理 Django

【CRM客户关系管理】07.自动发现APP注册并显示列表

admin2018年11月25日 15:25 Django | Html | Python 1044人已围观

DjangoCRM客户关系管理简介 使用Django2.1.3+Bootstrap实现CRM系统,仿照Django Admin重写后台 Github地址:https://github.com/xyliurui/DjangoCRM Django版本:2.1.3

## 注册APP列表显示 从这儿起,难度就有增加了 ### 自动发现app和注册 可以实现页面显示所有APP和对应的表名 #### 创建app_setup.py djadmin应用下创建app_setup.py文件 ```python from django import conf def djadmin_auto_discover(): for app_name in conf.settings.INSTALLED_APPS: try: # 去每个app下执行djadmin.py文件 # crm.apps.CrmConfig和crm需要做判定 mod = __import__('{}.djadmin'.format(app_name if 'Config' not in app_name else app_name.split('.')[0])) # 打印每个app已注册的model名字 print(mod.djadmin) # 会打印:<module 'crm.djadmin' from 'E:\\Sync\\OneDrive\\PycharmProjects\\DjangoCRM\\crm\\djadmin.py'> except ImportError: pass ``` 动态获取settings里面所有添加的app名字 Python `__import__()` 函数,具体用法查看 http://www.runoob.com/python/python-func-\_\_import\_\_.html - `__import__()` 函数用于动态加载类和函数 。 - 如果一个模块经常变化就可以使用 `__import__()` 来动态载入。 #### 返回全局字典 在djadmin应用下创建sites.py文件 ```python 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() ``` #### 应用下创建djadmin.py文件 crm应用下创建djadmin.py文件,用于注册模型 ```python from djadmin.sites import site from crm import models print('crm models...') # 注册model class CustomerInfoAdmin(object): list_display = ['name', 'contact_type', 'contact', 'consultant', 'consult_content', 'status', 'created_time'] list_filter = ['source', 'consultant', 'status', 'created_time'] search_fields = ['contact', 'consultant__name'] site.register(models.CustomerInfo, CustomerInfoAdmin) ``` #### djadmin应用下添加执行入口 修改djadmin应用下的views.py文件,增加 ```python from djadmin import app_setup app_setup.djadmin_auto_discover() from djadmin.sites import site print('site:', site.enable_admins) ``` 当程序一启动就会打印入口的信息 ```bat manage.py runserver 8000 Performing system checks... crm models... <module 'crm.djadmin' from 'E:\\Sync\\OneDrive\\PycharmProjects\\DjangoCRM\\crm\\djadmin.py'> site: {'crm': {'customerinfo': <class 'crm.djadmin.CustomerInfoAdmin'>}} ``` 会根据sites.py的配置显示字典信息。 ### 前端页面显示 修改djadmin应用下的index视图,增加视图的参数 ```python @login_required def index(request): return render(request, 'djadmin/index.html', { 'site': site }) ``` 修改djadmin/templates/djadmin/index.html页面显示 字典样式:`{'crm': {'customerinfo': <class 'crm.djadmin.CustomerInfoAdmin'>, 'userprofile': <class 'djadmin.djadmin_base.BaseDjAdmin'>, ...},...}` 模板中进行遍历 ```html {% extends 'djadmin/base.html' %} {% block title %} 主页 - 后台管理 {% endblock %} {% block content %} <h1 class="page-header">所有应用</h1> {% for app_name, app_models in site.enable_admins.items %} <table class="table table-striped"> <thead> <tr> <th>{{ app_name }}</th> </tr> </thead> <tbody> {% for model_name in app_models %} <tr> <td><a href="#">{{ model_name }}</a></td> <td>增加</td> <td>修改</td> </tr> {% endfor %} </tbody> </table> {% endfor %} {% endblock %} ``` ![BLOG_20181125_152857_33](/media/blog/images/2018/11/BLOG_20181125_152857_33.png "博客图集BLOG_20181125_152857_33.png") 修改crm应用下的djadmin.py文件,增加注册其他models ```python from djadmin.sites import site from crm import models print('crm models...') # 注册model class CustomerInfoAdmin(object): list_display = ['name', 'contact_type', 'contact', 'consultant', 'consult_content', 'status', 'created_time'] list_filter = ['source', 'consultant', 'status', 'created_time'] search_fields = ['contact', 'consultant__name'] site.register(models.CustomerInfo, CustomerInfoAdmin) site.register(models.Role) site.register(models.Menu) site.register(models.UserProfile) ``` 刷新 http://127.0.0.1:8000/djadmin/ 页面 ![BLOG_20181125_152848_63](/media/blog/images/2018/11/BLOG_20181125_152848_63.png "博客图集BLOG_20181125_152848_63.png") ### 如何在视图中获取模型实例 #### 注册模型类属性赋值 修改djadmin应用下的sites.py文件,增加`admin_class.model = model_class` ```python 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_verbose_name = model_class._meta.verbose_name # print(model_verbose_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() ``` 此时重新运行项目会报错 ```bat AttributeError: 'NoneType' object has no attribute 'model' ``` 是因为我们在注册model的时候,有的写了自定义的model类`site.register(models.CustomerInfo, CustomerInfoAdmin)`,有的没写`site.register(models.Role)`,而我们都统一的赋值,导致那些没写自定义model类(空的)赋值的时候就会报NoneType错误 > django自带的自定义admin类的写法继承了ModelAdmin,那注册的时候为什么有的没写自定义admin类没有报错呢?是因为继承的ModelAdmin帮我们写了(里面其实都定义为空了),我们模仿django admin的写法,也写个父类。 #### 注册模型类继承 在djdadmin应用下新建个djadmin_base.py,写个父类 ```python # djadmin/djadmin_base.py class BaseDjAdmin(object): pass ``` 修改crm应用下的djadmin.py文件,继承`BaseDjAdmin` ```python from djadmin.sites import site from crm import models from djadmin.djadmin_base import BaseDjAdmin print('crm models...') # 注册model class CustomerInfoAdmin(BaseDjAdmin): # 不使用object,直接继承BaseDjAdmin list_display = ['name', 'contact_type', 'contact', 'consultant', 'consult_content', 'status', 'created_time'] list_filter = ['source', 'consultant', 'status', 'created_time'] search_fields = ['contact', 'consultant__name'] site.register(models.CustomerInfo, CustomerInfoAdmin) site.register(models.Role) site.register(models.Menu) site.register(models.UserProfile) ``` 修改djadmin应用下的sites.py文件 如果传值`site.register(models.CustomerInfo, CustomerInfoAdmin)`那么`admin_class`就等于`CustomerInfoAdmin`;如果没有传值`site.register(models.Role)`,就使用默认值`admin_class=BaseAdmin` ```python from djadmin.djadmin_base import BaseDjAdmin class AdminSite(object): def __init__(self): self.enable_admins = {} # 两个参数,一个表名,一个自定义的admin类 def register(self, model_class, admin_class=BaseDjAdmin): """注册admin表""" # print('register',model_class,admin_class) # 获取app名字 app_name = model_class._meta.app_label # 获取表名 model_name = model_class._meta.model_name # 获取表别名 # model_verbose_name = model_class._meta.verbose_name # print(model_verbose_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() ``` 访问 http://127.0.0.1:8000/djadmin/ 页面也是正常显示的 ![BLOG_20181125_152823_32](/media/blog/images/2018/11/BLOG_20181125_152823_32.png "博客图集BLOG_20181125_152823_32.png") 会显示应用的名称,和已经注册的model ![BLOG_20181125_152815_69](/media/blog/images/2018/11/BLOG_20181125_152815_69.png "博客图集BLOG_20181125_152815_69.png")

很赞哦! (0)

文章交流

  • emoji
0人参与,0条评论

当前用户

未登录,点击   登录

站点信息

  • 建站时间:网站已运行2075天
  • 系统信息:Linux
  • 后台程序:Python: 3.8.10
  • 网站框架:Django: 3.2.6
  • 文章统计:256 篇
  • 文章评论:60 条
  • 腾讯分析网站概况-腾讯分析
  • 百度统计网站概况-百度统计
  • 公众号:微信扫描二维码,关注我们
  • QQ群:QQ加群,下载网站的学习源码
返回
顶部
标题 换行 登录
网站