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

【CRM客户关系管理】08.取出app中model的值,根据list_display配置生成数据列表

admin2018年11月25日 19:52 Django | Html | Python 1362人已围观

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

## 根据注册models配置生成数据列表 ### 取出app中model的值 #### models详情视图table_detail 在djadmin应用的views.py新建视图 ```python @login_required def table_detail(request, app_name, model_name): """取出指定model里的数据返回到前端""" # 拿到admin_class后,通过它获取model admin_class = site.enable_admins[app_name][model_name] queryset = admin_class.model.objects.all() print(queryset) return render(request, 'djadmin/table_detail.html', locals()) ``` #### 创建详情的模板table_detail.html ```html {% extends 'djadmin/base.html' %} {% block title %} 数据表详情 - 后台管理 {% endblock %} {% block content %} <h1 class="page-header">应用 - {{ app_name }}</h1> {{ queryset }} <table class="table table-striped"> <thead> <tr> <th>{{ app_name }}</th> </tr> </thead> <tbody> </tbody> </table> {% endblock %} ``` #### models详情url 修改djadmin应用下的urls,增加详情路由 ```python from django.urls import path from djadmin.views import index, user_login, user_logout, table_detail app_name = 'djadmin' urlpatterns = [ path('login/', user_login, name='user_login'), # djAdmin登录 path('logout/', user_logout, name='user_logout'), # djAdmin登出 path('', index, name='index'), # djAdmin主页 path('<str:app_name>/<str:model_name>/', table_detail, name='table_detail'), # 数据表详情 ] ``` #### 修改index.html增加详情链接 ```html <td><a href="{% url 'djadmin:table_detail' app_name=app_name model_name=model_name %}">{{ model_name }}</a></td> ``` 访问这四个页面的详情链接 ![BLOG_20181125_195412_60](/media/blog/images/2018/11/BLOG_20181125_195412_60.png "博客图集BLOG_20181125_195412_60.png") ```bat <QuerySet [<CustomerInfo: 测试>]> [10/Nov/2018 10:49:23] "GET /djadmin/crm/customerinfo/ HTTP/1.1" 200 4592 <QuerySet [<UserProfile: LR>]> [10/Nov/2018 10:49:26] "GET /djadmin/crm/role/ HTTP/1.1" 200 4587 <QuerySet [<UserProfile: LR>]> [10/Nov/2018 10:49:28] "GET /djadmin/crm/menu/ HTTP/1.1" 200 4587 <QuerySet [<UserProfile: LR>]> [10/Nov/2018 10:49:31] "GET /djadmin/crm/userprofile/ HTTP/1.1" 200 4587 ``` #### 判断注册类实例化 最终打印出来的`queryset = admin_class.model.objects.all()`有三个是相同的,也就是没注册三个model里面得到值是一样 原因分析:因为没注册的三个mdoel都共享同一个BaseDjAdmin内存对象(三个model内存地址一样),我们只需要实例化就可以了(实例化后就都有单独的内存空间了) 修改djadmin/sites.py文件,增加判断实例化对象 ```python from djadmin.djadmin_base import BaseDjAdmin 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) if admin_class: # 如果写了注册的类,就实例化自己 admin_class = admin_class() else: # 如果没有写注册的类,就用BaseDjAdmin实例化,防止使用相同的内存地址 admin_class = BaseDjAdmin() # 把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 [10/Nov/2018 11:11:22] "GET /djadmin/ HTTP/1.1" 200 5415 <QuerySet [<CustomerInfo: 测试>]> [10/Nov/2018 11:11:24] "GET /djadmin/crm/customerinfo/ HTTP/1.1" 200 4592 <QuerySet [<Role: 销售>, <Role: admin>]> [10/Nov/2018 11:11:27] "GET /djadmin/crm/role/ HTTP/1.1" 200 4605 <QuerySet [<Menu: 客户库>, <Menu: 主页(绝对)>, <Menu: 主页(动态)>]> [10/Nov/2018 11:11:31] "GET /djadmin/crm/menu/ HTTP/1.1" 200 4655 <QuerySet [<UserProfile: LR>]> [10/Nov/2018 11:11:35] "GET /djadmin/crm/userprofile/ HTTP/1.1" 200 4587 ``` ### 根据list_display配置生成数据列表 通过自定义的`admin_class`类,循环出`list_display`所有的列 在crm应用下djadmin.py配置中`list_display = ['name', 'contact_type', 'contact', 'consultant', 'consult_content', 'status', 'created_time']` #### 显示表头 修改table_detail.html遍历出上方的列表 ```html {% extends 'djadmin/base.html' %} {% block title %} 数据表详情 - 后台管理 {% endblock %} {% block content %} <h1 class="page-header">应用 - {{ app_name }}</h1> {{ queryset }} <table class="table table-striped"> <thead> <tr> {% for display_field in admin_class.list_display %} <th>{{ display_field }}</th> {% endfor %} </tr> </thead> <tbody> </tbody> </table> {% endblock %} ``` ![BLOG_20181125_195252_44](/media/blog/images/2018/11/BLOG_20181125_195252_44.png "博客图集BLOG_20181125_195252_44.png") 下面通过自定义模板标签显示表头的别名,也就是模型中定义的`verbose_name` #### 自定义模板标签 djadmin应用下新建python Package,取名为**templatetags**,然后再这个包内创建djadmin_tags.py文件 ```python from django.template import Library from django.utils.safestring import mark_safe register = Library() # 显示模型表的中文名称 @register.simple_tag def build_table_head_name(admin_class): th = '' for display_field in admin_class.list_display: # 获取列中的字段对象 display_field_obj = admin_class.model._meta.get_field(display_field) # print(display_field_obj.verbose_name) tmp = "<th>{}</th>".format(display_field_obj.verbose_name) th += tmp return mark_safe(th) # 显示表数据 @register.simple_tag def build_table_body(obj, admin_class): """ 生成一条记录的html元素 :param obj: 一个模型查询集中的一个对象 :param admin_class: 自定义注册的类 :return: 得到这个对象要求显示的所有列 """ td = '' for display_field_name in admin_class.list_display: # 根据属性名,获取对象的属性值,两个参数,一个对象obj,一个列名 display_field_data = getattr(obj, display_field) # 获取一个对象的属性值,例如<CustomerInfo: 小东>对象,得到他的name属性,值为小东 tmp = "<td>{}</td>".format(display_field_data) td += tmp return mark_safe(td) ``` #### 数据列表中使用模板标签 - 首先导入`{% load djadmin_tags %}` - 遍历查询集,得到每一个对象 - 将对象和自定义的注册类两个参数传入到模板标签 ```html {% extends 'djadmin/base.html' %} {% load djadmin_tags %} {% block title %} 数据表详情 - 后台管理 {% endblock %} {% block content %} <h1 class="page-header">应用 - {{ app_name }}</h1> {{ queryset }} <table class="table table-striped"> <thead> <tr> <!-- {% for display_field in admin_class.list_display %} <th>{{ display_field }}</th> {% endfor %} --> {% build_table_head_name admin_class %} </tr> </thead> <tbody> {% for obj in queryset %} <tr> {% build_table_body obj admin_class %} </tr> {% endfor %} </tbody> </table> {% endblock %} ``` 现在访问 http://127.0.0.1:8000/djadmin/crm/customerinfo/ 就可以看到相关的数据 ![BLOG_20181125_195241_30](/media/blog/images/2018/11/BLOG_20181125_195241_30.png "博客图集BLOG_20181125_195241_30.png") 但是其中的选择项的列是数字,比如status显示的1,2,想要显示`未报名`,`已报名`等 #### 修改模板标签选择项显示方式 因为有的字段有choices,有的字段没有choices,需要添加一个判断 - `models.CustomerInfo._meta.fields` 获取model所有字段的对象 - `models.CustomerInfo._meta.get_field('status')` 取一个字段的对象 - `get_xxxx_display` 显示choices里面的值 继续修改模板标签`build_table_body(obj, admin_class)`函数 ```python # 显示表数据 @register.simple_tag def build_table_body(obj, admin_class): """ 生成一条记录的html元素 :param obj: 一个模型查询集中的一个对象 :param admin_class: 自定义注册的类 :return: 得到这个对象要求显示的所有列 """ td = '' for display_field in admin_class.list_display: # 获取列中的字段对象 display_field_obj = admin_class.model._meta.get_field(display_field) # print(display_field_obj) # 字段对象choices方法,如果有choices,则使用get_xxx_display if display_field_obj.choices: print('get_{}_display'.format(display_field)) display_field_data = getattr(obj, 'get_{}_display'.format(display_field))() # 使用get_xxx_display()需要带括号,调用函数执行结果,而不带括号得到的是函数对象 else: # 根据属性名,获取对象的属性值,两个参数,一个对象obj,一个列名 display_field_data = getattr(obj, display_field) # 获取一个对象的属性值,例如<CustomerInfo: 小东>对象,得到他的name属性,值为小东 tmp = "<td>{}</td>".format(display_field_data) td += tmp return mark_safe(td) ``` 现在刷新 http://127.0.0.1:8000/djadmin/crm/customerinfo/ 页面 ![BLOG_20181125_195220_76](/media/blog/images/2018/11/BLOG_20181125_195220_76.png "博客图集BLOG_20181125_195220_76.png") 所有选择项就变成可识别的内容了。

很赞哦! (0)

文章交流

  • emoji
0人参与,0条评论

当前用户

未登录,点击   登录

站点信息

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