有时候我们想要修改xadmin详情页字段的显示方式,比如django默认的ImageField在后台显示的是image的url,我们更希望看到image的缩略图;再比如django将多对多字段显示为多选的下拉框或者左右选择栏的方式,向图片展示的这两种:

如果我想要上面这种带搜索功能并且只占一行的效果该如何做呢?

这就需要我们自定义widget插件了。

那么什么是widget插件呢?

django admin在渲染form表单时,会根据字段的类型(ImageField、DateTtimeField、TextField等等)将字段渲染成不同的展示效果,那么在哪里规定这些展示效果呢,就需要widget插件了,django中每种字段类型都会对应一种插件,插件规定了字体大小颜色排布方式等。插件本质就是一个class, django-xadmin的插件位于xadmin\widgets.py文件中。

下面就以多对多字段为例,介绍自定义widget方法。

定义widget:
xadmin\widgets.py

可以用self.attrs获取之前传递的request相关的参数

class M2MFilterWidget(forms.SelectMultiple):

    # media方法是引入你所需要的js、css文件
@property
def media(self):
# 共四个文件:bootstrap.min.css jquery-1.11.0.min.js selectpage.css selectpage.js,前两个系统已经加载,只需再加载后两个
return vendor('xadmin.widget.selectpage.js', 'xadmin.widget.selectpage.css') # render方法是渲染你要展示字段的样式,通常返回html字符串
def render(self, name, value, attrs=None):
# 将数据库中已经被选中的值展示到页面,要将value([1,3,5,8...]列表格式)转化为value_str(‘1,3,5,8’字符串格式)
value_str = ','.join(map(str, value)) if value else '' # 可以用self.attrs获取之前传递的request相关的参数
attrs = self.attrs # 获取多对多字段的所有可选选项传递到前端,以便前端进行搜索过滤
choices = self.choices.field._queryset
# choices_data格式固定
choices_data = [{'id': choice.id, 'name': choice.username} for choice in choices]
return mark_safe('<div >'
'<div class="m2mfilter" id="m2m_%s" style="display: none">%s</div>'
'<div class="col-md-12">'
'<input type="text" id="selectPage_%s" class="form-control" name="%s" value=%s placeholder="请输入查询关键字">'
'</div>'
'</div>'
%(name, choices_data, name, name, value_str))

  

注意:

引入的js css文件名必须是xadmin.widget.xxx.js、xadmin.widget.xxx.css格式,而且要放在xadmin/static/js、xadmin/static/css下面,具体原因我就不展开讲了,有兴趣你可以追踪下verdor这个函数里面就知道了。

另外如果你的需求和本例一样,'xadmin.widget.selectpage.js', 'xadmin.widget.selectpage.css'这两个文件可以评论或者私信和我要。也可以在这里下载

https://download.csdn.net/download/bocai_xiaodaidai/11422561

https://download.csdn.net/download/bocai_xiaodaidai/11422556

使用自定义的widget:
1、在详情页使用,要在adminx.py中设置

adminx.py

#kwargs['widget'] = M2MFilterWidget(attrs={'input_type': 'hidden', 'user_id':self.request.user.id})这种写法的作用是可以将当前请求的某些参数传递到widget中。因为在widget中是无法获取request相关参数的。

m2mfilter_list = ['interviewer_1', 'interviewer_2', 'interviewer_3']

    # 给当前模型所有ManyToManyField字段指定widget
# formfield_overrides = {models.ManyToManyField: {'widget': M2MFilterWidget}} #给当前模型某个Field字段指定widget
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name in self.m2mfilter_list:
kwargs['widget'] = M2MFilterWidget
#kwargs['widget'] = M2MFilterWidget(attrs={'input_type': 'hidden', 'user_id':self.request.user.id})
return db_field.formfield(**kwargs)
return super().formfield_for_dbfield(db_field, **kwargs)

大功告成,打开浏览器就可以看到这个多对多字段的显示方式为下面这样了:

2、在自定义表单中使用

class BulkEditForm(forms.ModelForm):
class Meta:
model = HrUser
fields = ['username', 'owner'] widgets = {
'owner': M2MFilterWidget,
} class BulkEditAction(BaseActionView):
action_name = "bulk_edit_action"
description = '修改所选简历 所有者'
model_perm = 'change' # 这里要重写media方法加载静态文件
@property
def media(self):
return vendor('xadmin.widget.selectpage.js', 'xadmin.widget.selectpage.css') def do_action(self, queryset):
title = '请选择简历 所有者'
form = BulkEditForm()
hruser_projected = []
username_list = []
for obj in queryset:
username_list.append(obj.username)
if not is_group_member(self.request, settings.CONSTANTS['MANAGER_GROUP_NAME']):
hruser_projected.append('简历:' + obj.username) context = self.get_context()
context.update({
"title": title,
'queryset': queryset,
'usernames': ','.join(username_list),
'form': form,
"hruser_projected": hruser_projected,
"opts": self.opts,
"app_label": self.app_label,
})
return TemplateResponse(self.request,'xadmin/bulk_edit.html', context)

 

如果你想将ImageField字段显示为图片缩略图而非图片地址,可以看下我的这篇文章

https://blog.csdn.net/bocai_xiaodaidai/article/details/95179098

原文链接:https://blog.csdn.net/bocai_xiaodaidai/article/details/95172133

django-xadmin自定义widget插件(自定义详情页字段的显示样式)的更多相关文章

  1. Meteor 从一个列表页进入详情页怎样高速显示详情

    无论是做android开发,还是做网页web开发,都 会有列表,都须要点击列表进入列表项的详情页面,查看具体信息,能常情况下,我们都是将这一列表项的id传到详情页,由详情页再到数据库查询具体信息. 在 ...

  2. mongodb GridFS django FileFiled 默认 widget 只有一个文件上传框显示不了字段内容,重写widget

    首先,定位到:FileFiled 默认 widget 源码:mongoadmin包options.py中,如下: # Defaults for formfield_overrides. ModelAd ...

  3. Flutter实战视频-移动电商-44.详细页_首屏自定义Widget编写

    44.详细页_首屏自定义Widget编写 把详细页的图片.标题.编号和价格形成一个单独的widget去引用 详情页的顶部单独封装个插件 在pages下面新建detials_page的文件件并在里面新建 ...

  4. Flutter移动电商实战 --(44)详细页_首屏自定义Widget编写

    把详细页的图片.标题.编号和价格形成一个单独的widget去引用 详情页的顶部单独封装个插件 在pages下面新建detials_page的文件件并在里面新建页面details_top_area.da ...

  5. Android 自定义View修炼-自定义HorizontalScrollView视图实现仿ViewPager效果

    开发过程中,需要达到 HorizontalScrollView和ViewPager的效果,于是直接重写了HorizontalScrollView来达到实现ViewPager的效果. 实际效果图如下: ...

  6. Phpcms 详情页显示所属栏目的同级栏目

    Phpcms详情页是不显示所属栏目的同级栏目的,如果按下面的方式 {loop subcat($parentid) $v} <li{if $v[catid]==$catid} class=&quo ...

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

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

  8. 自定义 behavior - 完美仿 QQ 浏览器首页,美团商家详情页

    使用CoordinatorLayout打造各种炫酷的效果 自定义Behavior -- 仿知乎,FloatActionButton隐藏与展示 NestedScrolling 机制深入解析 一步步带你读 ...

  9. django xadmin(2) 在xadmin基础上完成自定义页面

    1.在xadmin.py,GlobalSettings中自定义菜单 2.自定义视图函数,并获取原来的菜单等一下信息(主要是为了用xadmin的模板),具体的自己看xadmin源码 3.在adminx. ...

随机推荐

  1. CodeChef FAVNUM FavouriteNumbers(AC自动机+数位dp+二分答案)

    All submissions for this problem are available. Chef likes numbers and number theory, we all know th ...

  2. Day 03 作业

    简述变量的组成 变量名,赋值符号,变量值 简述变量名的命名规范 变量名应该能反映变量值所描述的状态 变量名必须以字母数字下划线组合且不能以数字开头 变量名不能是关键字 简述注释的作用 让后面的代码失效 ...

  3. 开发 Laravel 扩展的基本流程

    创建一个空的laravel项目 composer create-project --prefer-dist laravel/laravel pkg 在新建的 laravel 项目中建立如下目录 qia ...

  4. 001_Java概述与环境搭建

    Java由来: SUN公司开发,95年推出,96年推出JDK1.0版本 09年被Oracle(甲骨文)收购 詹姆斯·高斯林被称作“Java之父” JavaSE:Java Standard Editoi ...

  5. 函数计算: 让小程序开发进入 Serverless 时代

    点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 | 吴天龙(木吴 ...

  6. python爬虫--代理.让你的ip在坚挺一会!!

    代理 代理简述 代理服务器:实现请求转发,从而可以实现更换请求的ip地址 在requests中如何将请求的ip进行更换 代理的匿名度: 透明:服务器知道你使用了代理并且知道你的真实ip 匿名:服务器知 ...

  7. CCF-CSP题解 201609-4 交通规划

    最小最短路径树. \(dis[j]==dis[i]+w(i,j)\)时,从\(w(i,j')\)和\(w(i,j)\)考虑.--从0分到100分. #include <bits/stdc++.h ...

  8. Codeforces Round #590 (Div. 3)

    A. Equalize Prices Again 题目链接:https://codeforces.com/contest/1234/problem/A 题意:给你 n 个数 , 你需要改变这些数使得这 ...

  9. C# yield关键字

    关于yield关键字,网上有很多文章介绍了,但是看了之后,虽然明白了"哦,原来是这么回事",但是在日常开发中并没有真正的用起来,所以,写此一篇,介绍一下在真正的项目中怎么使用这个关 ...

  10. 4、看源码MVC Controller如何调用Action

    Controller继承ControllrBase,ControllerBase继承IController,而IController里只有一个Execute方法 1.ControllrBase里的Ex ...