Django - Xadmin (三) 分页、搜索和批量操作

分页和 ShowList 类

因为 list_view 视图函数里面代码太多,太乱,所以将其里面的用于处理表头、处理表单数据的关键代码提取出来,作为函数包装到一个类当中,同时,将分页功能代码也封装到该类中。

ShowList 类

因为将代码封装成了一个类,最先重要的是初始化,这里的初始化所传参数如下:

def __init__(self, config, data_list, request):

config: 即每个表对应的配置类

data_list: 数据列表

request: 就是 Django 的响应对象

首先,需要引入分页类。实例化分页类对象。并将其作为类的变量以方便调用。

from Xadmin.utils.page import Pagination

其次,更改代码,一些关键变量此时需要加上 self 或者 self.config 等。

class ShowList(object):
def __init__(self, config, data_list, request):
self.config = config
self.data_list = data_list
self.request = request # 扩展分页类
current_page = int(self.request.GET.get("page", 1))
data_count = self.data_list.count()
base_path = self.request.path
self.pagination = Pagination(current_page, data_count, base_path, self.request.GET, per_page_num=1, pager_count=3)
self.data_page = self.data_list[self.pagination.start: self.pagination.end] def get_header(self):
# 处理表头
header_list = [] # 为list_display的每个字段都添加相应的表头
for field in self.config.new_display_list(): # 字段为数据表自带
if isinstance(field, str):
# 默认list_display
if field == '__str__':
val = self.config.model._meta.model_name.upper()
else:
field_obj = self.config.model._meta.get_field(field)
val = field_obj.verbose_name
# 字段为自添加函数
else:
# is_header判断是否在传表头时调用
val = field(self.config, is_header=True)
header_list.append(val) return header_list def get_body(self):
# 处理表单数据的列表
new_data_list = [] for data_obj in self.data_page:
temp = []
for field in self.config.new_display_list():
# 取数据对象相应的字段
if isinstance(field, str):
val = getattr(data_obj, field)
# 如果是根据该字段进入编辑页面
if field in self.config.list_display_links:
_url = self.config.get_change_url(data_obj)
val = mark_safe("<a href='%s'>%s</a>" % (_url, val))
else:
val = field(self.config, data_obj) temp.append(val) new_data_list.append(temp) return new_data_list

视图函数的改变

视图函数 list_view 现在只需要构建一个 ShowList 的实例对象传到前端即可。

# 构建ShowList列表
showlist = ShowList(self, data_list, request)

前端的改变

之前是直接使用从后端传来的数据变量,现在从后端传来的是 ShowList 实例对象,只需将原来的数据变量改成 showlist 调用相应函数即可。

加上了分页功能:调用 ShowList 类中 pagination 变量中的 page_html 方法。

<table class="table table-bordered table-striped">
<thead>
<tr>
{% for item in showlist.get_header %}
<td>{{ item }}</td>
{% endfor %} </tr>
</thead>
<tbody>
{% for new_data in showlist.get_body %}
<tr>
{% for data in new_data %}
<td>{{ data }}</td>
{% endfor %} </tr>
{% endfor %} </tbody>
</table>
<nav>
<ul class="pagination">
<li>{{ showlist.pagination.page_html | safe }}</li>
</ul>
</nav>

搜索

前端的搜索框

因为功能是根据后端 search_fields 列表来判断是否有搜索功能以及搜索的字段,同时通过从后端的 key_words 来保持搜索框内容:

{% if showlist.config.search_fields %}
<form action="" class="pull-right">
<input type="text" name="q" value="{{ showlist.config.key_words }}">
<button>搜索</button>
</form>
{% endif %}

后端的处理

在 ModelXadmin 类中增加一个变量 search_fields 来指定可以搜索的字段。默认为空,在每个表各自的配置类中可以加以指定。

search_fields = []

在 ModelXadmin 类中增加一个函数 get_search_condition 来获取搜索筛选的条件。

基于 Q 函数,以 或 为连接搜索条件。

def get_search_conditon(self, request):
key_words = request.GET.get("q", "")
self.key_words = key_words
from django.db.models import Q
search_connection = Q()
if key_words:
search_connection.connector = "or"
for field in self.search_fields:
search_connection.children.append((field + "__contains", key_words)) return search_connection

最后在 list_view 中进行实际数据过滤操作。

# 获取search的Q对象
search_connection = self.get_search_conditon(request) # 筛选数据
data_list = self.model.objects.filter(search_connection)

批量操作

与 admin 类似,批量操作也是选中多个数据后在下拉框中选中要做的操作。同样,定义批量操作的代码需要放在各个表的配置类中。

前端

因为批量操作需要对表单数据进行处理,所以要将整个表单也放到 form 中。

<form method="post">
{% csrf_token %}
<select name="action" id="" style="width: 200px;padding: 5px 8px;display: inline-block">
<option value="">------</option>
{% for action in showlist.get_action_list %}
<option value="{{ action.name }}">{{ action.short_description }}</option>
{% endfor %} </select>
<button class="btn btn-info">Go</button>
<table>表</table>
<nav>分页</nav>
</form>

表的配置类

定义批量操作函数。

给函数加上 short_description 属性来描述和在前端显示。

然后将批量操作函数加到配置类的 actions 列表中。

def patch_init(self, request, queryset):
queryset.update(price=123) patch_init.short_description = "批量初始化" actions = [patch_init]

后端

表的配置类中,只是对批量操作函数的定义,真正运行时其实是在后端。

从前端中获取要进行的操作和数据,并运行。重点在 action_func(request, queryset)

def list_view(self, request):

	if request.method == "POST":
action = request.POST.get("action")
selected_pk = request.POST.getlist("selected_pk")
action_func = getattr(self, action)
queryset = self.model.objects.filter(pk__in=selected_pk)
action_func(request, queryset)

默认批量处理

前面提到批量操作函数的定义在各个表的配置类中,可以为每个表定义各自的操作。而一些所有表都需要的批量操作,即默认批量操作,如批量删除,也是可以实现的。

在 ModelXadmin 类中进行批量操作函数定义并加到 actions 列表中,这样,就是默认批量操作了。


def patch_delete(self, request, queryset):
queryset.delete() patch_delete.short_description = "批量删除" def new_actions(self):
temp = []
temp.append(ModelXadmin.patch_delete)
temp.extend(self.actions) return temp

完整代码:GitHub地址

Django - Xadmin (三) 分页、搜索和批量操作的更多相关文章

  1. 第三百八十九节,Django+Xadmin打造上线标准的在线教育平台—列表筛选结合分页

    第三百八十九节,Django+Xadmin打造上线标准的在线教育平台—列表筛选结合分页 根据用户的筛选条件来结合分页 实现原理就是,当用户点击一个筛选条件时,通过get请求方式传参将筛选的id或者值, ...

  2. 第三百八十八节,Django+Xadmin打造上线标准的在线教育平台—网站列表分页

    第三百八十八节,Django+Xadmin打造上线标准的在线教育平台—网站列表分页 分页可以用一个第三方分页模块django-pure-pagination 下载地址:https://github.c ...

  3. 第三百九十六节,Django+Xadmin打造上线标准的在线教育平台—其他插件使用说,自定义列表页上传插件

    第三百九十六节,Django+Xadmin打造上线标准的在线教育平台—其他插件使用说,自定义列表页上传插件 设置后台列表页面字段统计 在当前APP里的adminx.py文件里的数据表管理器里设置 ag ...

  4. 第三百九十五节,Django+Xadmin打造上线标准的在线教育平台—Xadmin集成富文本框

    第三百九十五节,Django+Xadmin打造上线标准的在线教育平台—Xadmin集成富文本框 首先安装DjangoUeditor3模块 Ueditor HTML编辑器是百度开源的HTML编辑器 下载 ...

  5. 第三百九十四节,Django+Xadmin打造上线标准的在线教育平台—Xadmin后台进阶开发配置2,以及目录结构说明

    第三百九十四节,Django+Xadmin打造上线标准的在线教育平台—Xadmin后台进阶开发配置2,以及目录结构说明 设置后台列表页面可以直接修改字段内容 在当前APP里的adminx.py文件里的 ...

  6. 第三百九十三节,Django+Xadmin打造上线标准的在线教育平台—Xadmin后台进阶开发配置

    第三百九十三节,Django+Xadmin打造上线标准的在线教育平台—Xadmin后台进阶开发配置 设置后台某个字段的排序规则 在当前APP里的adminx.py文件里的数据表管理器里设置 order ...

  7. 第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承

    第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承 母板-子板-母板继承 母板继承就是访问的页面继承一个母板,将访问页面的内容引入到母板里指定的地方,组合成一个新页 ...

  8. 第三百八十二节,Django+Xadmin打造上线标准的在线教育平台—xadmin管理员详情页面布局,导航图标设置

    第三百八十二节,Django+Xadmin打造上线标准的在线教育平台—xadmin进阶 1.后台管理员详情页面布局 后台管理员详情页面,区块是可以拖动的,而且分为了很多个区块 这个页面的布局在xadm ...

  9. 第三百八十一节,Django+Xadmin打造上线标准的在线教育平台—xadmin全局配置

    第三百八十一节,Django+Xadmin打造上线标准的在线教育平台—xadmin全局配置 1.xadmin主题设置 要使用xadmin主题,需要在一个app下的adminx.py后台注册文件里,写一 ...

随机推荐

  1. CSS——相对定位、绝对定位、固定定位

    相对定位: position:relative 当元素被设置相对定位或是绝对定位后,将自动产生层叠,他们的层叠级别自然的高于文本流,除非设置其z-index值为负值. 并且我们发现当相对定位元素进行位 ...

  2. wepy 中文乱码

    <view class="loginTitle"> <view class="{{currentTab==0?'select':'default'}}& ...

  3. 【bzoj2064】【分裂】状态压缩表示合并子集

    (上不了p站我要死了,画师当然是wlop大大啦) 感觉这个做法还是挺难想的. 但还是总结一下思路吧.. "只可意会不可言传的状压dp"(乱说) Description 背景: 和久 ...

  4. HDU 6614 AND Minimum Spanning

    Time limit 1000 ms Memory limit 131072 kB OS Windows 中文题意 给一张n个点的无向完全图(输入一个n就完事了),每个点标号为1~n,每条边的边权为它 ...

  5. 【bzoj2946】[Poi2000]公共串

    *题目描述: 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计算最长公共子串的长度 l 输出结果 *输入: 文件的第一行是整数 n,1<=n<=5, ...

  6. Spark Streaming的优化之路—从Receiver到Direct模式

    作者:个推数据研发工程师 学长     1 业务背景   随着大数据的快速发展,业务场景越来越复杂,离线式的批处理框架MapReduce已经不能满足业务,大量的场景需要实时的数据处理结果来进行分析.决 ...

  7. JS判断Android、iOS或浏览器的多种方法(四种方法)

    第一种:通过判断浏览器的userAgent,用正则来判断是否是ios和Android客户端. 代码如下: <script type="text/javascript"> ...

  8. Python编程:从入门到实践—函数

    从函数中修改列表 一家为用户提交的设计制作3D打印模型的公司,需要打印的设计存储在一个列表中,打印后移到另一个列表中. #!/usr/bin/env python # -*- coding:utf-8 ...

  9. duliu题之狼抓兔子题解

    拖了将近5天的正解和AC.........emmmmm........... 事实告诉我们这种毒瘤题一定要建双向边(用了不知道多少个小时质疑建边的人欲哭无泪) 心态爆炸的传送 题了个面 这是个求最小割 ...

  10. qbzt day5 上午

    动态规划 递推  递归   记忆化搜索 斐波那契数列 1.用其他已经计算好的结果计算自己的结果(递推) 2.用自己的值计算别人的值(考虑对之后的项做出的贡献) cin >> n; f[]= ...