个人博客,欢迎查看:https://blog.starmeow.cn/
Github地址:https://github.com/xyliurui/DjangoCRM
根据注册models配置生成数据列表
取出app中model的值
models详情视图table_detail
在djadmin应用的views.py新建视图
@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
{% 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,增加详情路由
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增加详情链接
<td><a href="{% url 'djadmin:table_detail' app_name=app_name model_name=model_name %}">{{ model_name }}</a></td>
访问这四个页面的详情链接
![](https://img.haomeiwen.com/i5730845/e9423695e9f6fac5.png)
<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文件,增加判断实例化对象
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()
然后访问各个链接,都是返回各自的查询集了
[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遍历出上方的列表
{% 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 %}
![](https://img.haomeiwen.com/i5730845/9c3931e6ebb72506.png)
下面通过自定义模板标签显示表头的别名,也就是模型中定义的verbose_name
自定义模板标签
djadmin应用下新建python Package,取名为templatetags,然后再这个包内创建djadmin_tags.py文件
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 %}
- 遍历查询集,得到每一个对象
- 将对象和自定义的注册类两个参数传入到模板标签
{% 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/ 就可以看到相关的数据
![](https://img.haomeiwen.com/i5730845/3ca49746d926ed34.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)
函数
# 显示表数据
@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/ 页面
![](https://img.haomeiwen.com/i5730845/e74addce8920aab8.png)
所有选择项就变成可识别的内容了。
网友评论