Django 自带的 admin 组件可以自定义配置,本文实现 Xadmin 对自定义显示数据列 (list_display) 的配置。

构建表单数据

模板层

从视图函数传来的数据变量是双层列表,第一层是数据库当中的每一条数据,第二层是每一条数据的各个字段值。

类似于

[
["1","King","益达出版社",12],
["2","Fight","西湖出版社",22],
]

所以在模板层通过双循环来取数据。


<tbody>
{% for new_data in new_data_list %}
<tr>
{% for data in new_data %}
<td>{{ data }}</td>
{% endfor %} </tr>
{% endfor %}
</tbody>

ModelXadmin 类

首先,设置一个列表变量 list_display 存储要显示数据表列信息。该变量不能再视图函数中设置,应该作为类的一个成员变量。该变量需要设置默认值 list_display = ["__str__", ] ,使在没有 Model 配置类的 model 中数据也能正常显示。

显示的列字段分为两种,一种是数据表自带的,一种是个人在配置类中设置的函数。

自带的列字段的处理

判断 list_display 中的元素是否为 str 类型,如果是代表为自带列字段,对每个数据对象用 getattr 函数获取相应的字段值。

# 取数据对象相应的字段
if isinstance(field, str):
val = getattr(data_obj, field)

配置类中函数的处理

如果是函数,就执行该函数,添加的是该函数的返回值。

val = field(self, data_obj)

完整代码:

# 处理表单数据的列表
new_data_list = [] for data_obj in data_list:
temp = []
for field in self.list_display:
# 取数据对象相应的字段
if isinstance(field, str):
val = getattr(data_obj, field)
else:
val = field(self, data_obj)
temp.append(val) new_data_list.append(temp)

Model 配置类

在每个 app 下面的 Xadmin.py 文件中对数据表进行注册和配置。

list_play 变量

更改自己的 list_display 变量,将想显示的数据表中的字段加入进去。也可以加入函数字段。

函数作为列字段

当作为表单内容时,函数返回的是字符串,字符串可以是 HTML 标签。如果是 HTML 标签,则返回值需要经过 mark_safe 处理。

如果返回的是 a 标签,其中的 href 属性所用链接应当设置为相对路径,并且此处会用到 url 反向解析的内容。

def edit(self, obj=None):

	url = reverse('change', args=(obj.pk, ))
return mark_safe('<a href="'+url+'">编辑</a>')

构建表头

模板层

传表头的数据时使用的是一维列表,即每个列字段的名称,所以只需要一个循环。

<thead>
<tr>
{% for item in header_list %}
<td>{{ item }}</td>
{% endfor %}
</tr>
</thead>

ModelXadmin 类

为 list_display 的每个字段都添加相应的表头。分为三种情况,一是默认 list_display 列表,二是自定义的 list_display 列表,三是为函数列字段添加表头。

默认 list_display

若判断 list_display 中的元素为 __str__ 则认为是为默认的 list_display 添加表头,这里我们将 model_name 全部大写作为表头。

if isinstance(field, str):
# 默认list_display
if field == '__str__':
val = self.model._meta.model_name.upper()

自定义 list_display

通过数据表类中的 meta 对象获取相应的字段值,若想显示中文,则应在数据表类中添加 verbose_name 属性。

 # 字段为数据表自带
if isinstance(field, str):
# 默认list_display
if field == '__str__':
val = self.model._meta.model_name.upper()
else:
field_obj = self.model._meta.get_field(field)
val = field_obj.verbose_name

函数列字段

传回作为表头的确认信息,由 Model 配置类进行处理。

# is_header判断是否在传表头时调用
val = field(self, is_header=True)

完整添加表头代码:

# 处理表头
header_list = [] # 为list_display的每个字段都添加相应的表头
for field in self.list_display: # 字段为数据表自带
if isinstance(field, str):
# 默认list_display
if field == '__str__':
val = self.model._meta.model_name.upper()
else:
field_obj = self.model._meta.get_field(field)
val = field_obj.verbose_name
# 字段为自添加函数
else:
# is_header判断是否在传表头时调用
val = field(self, is_header=True)
header_list.append(val)

Model 配置类

别的地方不需要动,在判断传回的是表头时返回自定义表头。

# 用在传表头的时候
if is_header is True:
return "操作"

完整 ModelXadmin 代码:

class ModelXadmin(object):
# 存放要显示哪些字段的列表
list_display = ["__str__", ] def __init__(self, model, site):
self.model = model
self.site = site def list_view(self, request):
# 所有的数据
data_list = self.model.objects.all()
# 数据表的名称
model_name = self.model._meta.model_name # 处理表头
header_list = [] # 为list_display的每个字段都添加相应的表头
for field in self.list_display: # 字段为数据表自带
if isinstance(field, str):
# 默认list_display
if field == '__str__':
val = self.model._meta.model_name.upper()
else:
field_obj = self.model._meta.get_field(field)
val = field_obj.verbose_name
# 字段为自添加函数
else:
# is_header判断是否在传表头时调用
val = field(self, is_header=True)
header_list.append(val) # 处理表单数据的列表
new_data_list = [] for data_obj in data_list:
temp = []
for field in self.list_display:
# 取数据对象相应的字段
if isinstance(field, str):
val = getattr(data_obj, field)
else:
val = field(self, data_obj)
temp.append(val) new_data_list.append(temp) return render(request,
"list_view.html",
{
"data_list": data_list,
"model_name": model_name,
"new_data_list": new_data_list,
"header_list": header_list,
}
)

完整 Model 配置类 BookConfig 代码:

class BookConfig(ModelXadmin):

    def edit(self, obj=None, is_header=False):

        # 用在传表头的时候
if is_header is True:
return "操作" url = reverse('change', args=(obj.pk, ))
return mark_safe('<a href="'+url+'">编辑</a>') def delete(self, obj=None, is_header=False): # 用在传表头的时候
if is_header is True:
return "操作" url = reverse('delete', args=(obj.pk,))
return mark_safe('<a href="'+url+'">删除</a>') def check(self, obj=None, is_header=False): # 用在传表头的时候
if is_header is True:
return "操作" return mark_safe('<input type="checkbox">') list_display = [check, "nid", "title", "price", "publish", edit, delete]

完整模板代码:

<h3>查看{{ model_name }}数据</h3>

<div class="container">
<div class="row">
<div class="col-md-9">
<table class="table table-bordered table-striped">
<thead>
<tr>
{% for item in header_list %}
<td>{{ item }}</td>
{% endfor %} </tr>
</thead>
<tbody>
{% for new_data in new_data_list %}
<tr>
{% for data in new_data %}
<td>{{ data }}</td>
{% endfor %} </tr>
{% endfor %} </tbody>
</table>
</div>
</div>
</div>

完成效果

GitHub 地址:https://github.com/protea-ban/oldboy/tree/master/s9day84/Xadmindemo

Django - Xadmin 组件(二)的更多相关文章

  1. Django - Xadmin 组件(一)

    Django - Xadmin 组件(一) Web 应用中离不开的就是后台管理, Django 自带的 admin 组件提供了一部分内容,但往往现实项目中会有更多的需求,所以自定义自己的后台管理就十分 ...

  2. Django+xadmin打造在线教育平台(二)

    三.xadmin后台管理 3.1.xadmin的安装 django2.0的安装(源码安装方式): https://github.com/sshwsfc/xadmin/tree/django2 把zip ...

  3. 第四百零二节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署,uwsgi安装和启动,nginx的安装与启动,uwsgi与nginx的配置文件+虚拟主机配置

    第四百零二节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署,uwsgi安装和启动,nginx的安装与启动,uwsgi与nginx的配置文件+虚拟主机配置 软件版本  uwsgi- ...

  4. Django框架(二十)—— Django rest_framework-认证组件

    目录 Django rest_framework-认证组件 一.什么是认证 二.利用token记录认证过的用户 1.什么是token 2.token的原理 3.cookie.session.token ...

  5. Django+xadmin打造在线教育平台(三)

    五.完成注册.找回密码和激活验证码功能 5.1.用户注册 register.html拷贝到templates目录 (1)users/views.py class RegisterView(View): ...

  6. django Form组件

    django Form组件 Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 小试牛刀 1.创建 ...

  7. Django+xadmin打造在线教育平台(一)

    目录 在线教育平台(一)      在线教育平台(二) 在线教育平台(三)      在线教育平台(四) 在线教育平台(五)      在线教育平台(六) 在线教育平台(七)      在线教育平台( ...

  8. Django admin组件源码流程

    admin 组件 Django 自带的用户后台组件 用于用户便携的操作 admin 组件核心 启动 注册 设计url 启动核心代码 每个app 通过 apps.py 扫描 admin.py 文件 并执 ...

  9. xadmin 组件拓展自定义使用

    xadmin 组件相关可选自定义字段 list_display 功能 设置默认的显示字段(列) 配置 list_display = ['name', 'desc', 'detail', 'degree ...

随机推荐

  1. ThinkPHP3.2 插入数据库数据,缓存问题

    每个字段都是有数据的,可是就是is_new插不进去, 最后的原因就是TP有数据库字段缓存,FUCK 把RunTIme下面的Data文件夹删除掉,在开发模式中就把自动缓存改成Fasle

  2. laravel 模型关联之(多对多)

    多对多 多对多就相当于一个专题Topic有多个文章,但是这多个文章又属于多个专题, 而且多对都必须有一个表是他们之间的关联关系表PostTopic Post表和Topic表之间没有直接的关联,而且通过 ...

  3. 关于使用sessionStorage报SecurityError错误的问题

    localStorage 永久保存 不同页面和标签页可以共享 关闭浏览器不会清除 sessionStorage 会话保存 不同页面和标签页不能共享 关闭浏览器会清除 遇到的问题:在firefox中报S ...

  4. SQL Server 索引维护:系统常见的索引问题

    在很多系统中,比如本人目前管理的数据库,索引经常被滥用,甚至使用DTA(数据库引擎优化顾问)来成批创建索引(DTA目前个人认为它的真正用处应该是在发现缺失的统计信息,在以前的项目中,用过一次DTA,里 ...

  5. session的应用----验证码

    昨天登录功能中叙述了密码 用户名的数据库验证以及转发 那么这篇文章在昨天的基础上 处理验证码的验证功能,今天需要用到session域,session用于一次会话. package cn.lijun.d ...

  6. 运行maven build报错No goals have been specified for this build.

    运行maven报错: [ERROR] No goals have been specified for this build. You must specify a valid lifecycle p ...

  7. 关于在datepicker中,只选年月

    有这么个需求,datepicker默认是选某个具体的日子的,但是现在只选到年月为止, solution: html如下: <div> <label for="startDa ...

  8. 全排列——DFS实现

    原创 之间就写过一篇全排列的博客:https://www.cnblogs.com/chiweiming/p/8727164.html 详细介绍请回看,用的方法(暂且就叫)是“交换法”,其实思路就是DF ...

  9. ComicEnhancerPro 系列教程十九:用JpegQuality看JPG文件的压缩参数

    作者:马健邮箱:stronghorse_mj@hotmail.com 主页:http://www.comicer.com/stronghorse/ 发布:2017.07.23 教程十九:用JpegQu ...

  10. excel文档中嵌入对象(excel、word等)

    //测试环境office2016.office365 string InsertPath= @"E:\\新建文件夹\\2.xls";//插入的文档路径 string openfil ...