1、源码安装(待补充)

安装方法

复制 xadmin 目录到你的项目(从github下载 https://github.com/sshwsfc/xadmin/tree/django2)

pip install httplib2 django-formtools django-crispy-forms

# setting.py

INSTALLED_APPS = [

...,

'xadmin',

'crispy_forms',

'reversion',

]

# urls.py

import xadmin

xadmin.autodiscover()

from xadmin.plugins import xversion

xversion.register_models()

urlpatterns = [

url(r'^admin/', xadmin.site.urls)

]

2、左边菜单名称的修改,修改apps.py文件

class BlogConfig(AppConfig):

name = 'blog'

verbose_name = u'博客'

还需要在该应用下的init.py下添加

default_app_config = "blog.apps.BlogConfig"

3、页面显示中文

# LANGUAGE_CODE = 'en-us'

LANGUAGE_CODE = 'zh-hans'

# TIME_ZONE = 'UTC'

TIME_ZONE = 'Asia/Shanghai'

4、修改后台显示的网站名称和footer名称,菜单样式

from xadmin import views

class BaseSetting(object):

enable_themes = True #开启主题选择

use_bootswatch = True

class GlobalSettings(object):

site_title = "我的管理系统" #设置左上角title名字

site_footer = "504工作室" #设置底部关于版权信息

#设置菜单缩放

menu_style = "accordion" #左侧导航条修改可折叠

global_models_icon = {

User: "glyphicon glyphicon-user", UserDistrict: "fa fa-cloud"

} # 设置models的全局图标

xadmin.site.register(views.BaseAdminView, BaseSetting)

xadmin.site.register(views.CommAdminView, GlobalSettings)

5、modelview里面可以指定的参数

list_display=[] #要显示的字段

search_fields=[] #搜索的字段

list_filter = [] #过滤器

date_hierarchy =['publication_date'] #添加过滤(这里是过滤日期)

ordering = ['-publication_date',] #排序(这里以日期排序,加‘-’表示降序)

filter_horizontal = ('authors',) #filter_horizontal 从‘多选框’的形式改变为‘过滤器’的方式,水平排列过滤器,必须是一个 ManyToManyField类型,且不能用于 ForeignKey字段,默认地,管理工具使用`` 下拉框`` 来展现`` 外键`` 字段

filter_vertical = ['authors',]#同上filter_horizontal,垂直排列过滤器

raw_id_fields = ['publisher',] #将ForeignKey字段从‘下拉框’改变为‘文本框’显示

list_editable = ['csdevice'] #在列表页可直接编辑的字段

model_icon = 'fa fa-user-secret' #图标样式

style_fields = {'csdevice': 'm2m_transfer','csservice': 'ueditor',} #字段显示样式

refresh_times = [10, 60] #自动刷新时间

show_detail_fields=['ttdsn'] #在指定的字段后添加一个显示数据详情的一个按钮

relfield_style = 'fk-ajax' #涉及到外键下拉的时候使用ajax搜索的方式而不是全部列出的方式,比如在分类下拉很多的情况下,这个功能就很好用

free_query_filter=['字段1','字段2',......]#默认为 True , 指定是否可以自由搜索. 如果开启自由搜索, 用户可以通过 url 参数来进行特定的搜索

exclude=['字段1','字段2',......]#隐藏字段

aggregate_fields = {"expire": "max"}# 列聚合,在list表格下面会增加一行统计的数据,可用的值:"count","min","max","avg", "sum"

# 添加数据时候,一步一步提供数据,分块显示

wizard_form_list = [

("基础信息", ("name", "contact", "telphone", "address")),

("其它信息", ("customer_id", "expire", "description")),

]

grid_layouts = ("table", "thumbnails") #列表的布局方式,是以表格一行一条的方式还是类似于缩略图的方式展示的

list_per_page = 50 # 每页显示数据的条数

list_max_show_all = 200 #每页最大显示数据的条数

list_display_links=[] #指定列表显示的哪列可以点击跳转到详情更新页

preserve_filters=True #详细页面,删除、修改,更新后跳转回列表后,是否保留原搜索条件

save_as = False#详细页面,按钮为“Sava as new” 或 “Sava and add another”

save_as_continue = True#点击保存并继续编辑

save_on_top = False#详细页面,在页面上方是否也显示保存删除等按钮

radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL #详细页面时,使用radio显示选项(FK默认使用select)

show_full_result_count = True #列表时,模糊搜索后面显示的数据个数样式

7、自定义显示界面

可分为Main主区域和Side侧边区域,Main或Side中又可通过Fieldset再分多个区域。Fieldset为一个元组,第一个字段为需要设置的名称,其它字段均为模型中的字段名。如下:

class DeviceAdmin(object):

...

form_layout = (

Main(

Fieldset('基础信息',

'site', 'device_name', 'device_id', 'device_type', 'account', 'password'),

Fieldset('EXTRA',

'device_model', 'supplier', 'responsible_by', 'device_ip', 'sn_number'),

),

Side(

Fieldset('其它',

'buy_date', 'expire_date', 'note', 'attachment', 'date'),

)

)

8、根据登录用户过滤数据

需要根据登录用户或组过滤数据时,xadmin.py中改为重写queryset方法即可。如下:

class DeviceAdmin(object):

...

def queryset(self):

"""函数作用:使当前登录的用户只能看到自己负责的设备"""

qs = super(DeviceAdmin, self).queryset()

if self.request.user.is_superuser:

return qs

return qs.filter(area_company=Group.objects.get(user=self.request.user))

9、文件上传

settings.py文件增加以下代码:

MEDIA_URL = "/media/"

MEDIA_ROOT = os.path.join(BASE_DIR, "media")

urls.py文件增加路由设置:

from django.conf.urls import url

from django.conf import settings

from django.views.static import serve

urlpatterns = [

url(r'^media/(?P.*)$', serve, {"document_root": settings.MEDIA_ROOT}),

]

然后就可以在models里面定义字段为图片或者文件类型了

class Userinfo(models.Model):

sex_choice={

('male','男'),

('female','女')

}

username=models.CharField("用户名",max_length=100)

sex=models.CharField('性别',max_length=10,choices=sex_choice,default='male')

image=models.ImageField('头像',upload_to='image/%Y%m',default='image/default.png',max_length=254)

10、增加自定义的actions操作,比如现在我需要对选中的用户批量加钱

1、创建adminx_actions.py文件,要代码如下

# coding:utf-8

from xadmin.plugins.actions import BaseActionView

from django.http import HttpResponse

class MoneyAddAction(BaseActionView):

# 这里需要填写三个属性

action_name = "money_add_100" #: 相当于这个 Action 的唯一标示, 尽量用比较针对性的名字

description = u'批量增加金钱' #: 描述, 出现在 Action 菜单中, 可以使用 ``%(verbose_name_plural)s`` 代替 Model 的名字.

model_perm = 'change' #: 该 Action 所需权限

# 而后实现 do_action 方法

def do_action(self, queryset):

# queryset 是包含了已经选择的数据的 queryset

for obj in queryset:

# obj 的操作

obj.money+=100

obj.save()

# 返回 HttpResponse

return HttpResponse("修改成功")

这里做药就是在do_action中对选中的queryset进行增删改查操作。

2、在adminx.py文件中,导入刚刚的文件并使用

from .adminx_actions import *

class UserAdmin(object):

list_display=['username','sex','image','money']

#list_filter=[]

model_icon='fa fa-address-card'

actions=[MoneyAddAction,] #这里使用刚刚创建的action

xadmin.site.register(Userinfo,UserAdmin)

如下图,刷新之后这里就有新建的action,点击之后则会执行相应的操作

image.png

11、图表的使用

在 Model OptionClass 中设定 data_charts 属性, 该属性为 dict 类型, key 是图表的标示名称, value 是图表的具体设置属性. 使用示例:

class RecordAdmin(object):

data_charts = {

"host_service_type_counts": {

'title' : '主机类型统计',

'x-field' : "service_type",

'y-field' : ("service_type"),

'option' : {

"series" : {"bars":{"align":"center", "barWidth": 0.8,"show":True}},

"xaxis" : {"aggregate":"count","mode":"categories"}

},

},

"host_idc_counts" : {

'title' : '机房统计',

'x-field' : "idc",

'y-field' : ("idc",),

'option' : {

"series" : {"bars":{"align":"center", "barWidth": 0.5,"show":True}},

"xaxis" : {"aggregate":"count","mode":"categories"}

}

}

}

图表的主要属性为:

title : 图表的显示名称

x-field : 图表的 X 轴数据列, 一般是日期, 时间等

y-field : 图表的 Y 轴数据列, 该项是一个 list, 可以同时设定多个列, 这样多个列的数据会在同一个图表中显示

order : 排序信息, 如果不写则使用数据列表的排序

在上面的属性中,如果只是这样子的话,默认展示的就是折线图,如果需要用到其它图表类型,可以重写option属性

data_charts = {

"host_service_type_counts": {

'title' : '主机类型统计',

'x-field' : "service_type",

'y-field' : ("service_type"),

'option' : {

"series" : {"bars":{"align":"center", "barWidth": 0.8,"show":True}},

"xaxis" : {"aggregate":"count","mode":"categories"}

},

},

"host_idc_counts" : {

'title' : '机房统计',

'x-field' : "idc",

'y-field' : ("idc",),

'option' : {

"series" : {"bars":{"align":"center", "barWidth": 0.5,"show":True}},

"xaxis" : {"aggregate":"count","mode":"categories"}

}

}

}

但是,到目前为止,仅发现以上的bars柱形图可以用,其它图形的设置没有找到。。。。

顺便提一下,在xadmin\static\xadmin\vendor\flot目录下,可以看到图表是使用jquery.flot.js渲染的,但是我使用里面的option参数去测试饼图的时候并没有成功,不懂要怎么处理。。。

============================2019.11.27更新内容==============

12、adminx.py配置views的时候,可以重定义以下函数实现其它自定义功能。

class JFLogsAdmin(object):

def queryset(self):

"""queryset对应的是列表页显示的数据内容"""

qs = super(JFLogsAdmin, self).queryset()

if not self.request.user.is_superuser:

qs=qs.filter(...) #按用户过滤

return qs

def formfield_for_dbfield(self, db_field, **kwargs):

"""formfield_for_dbfield是指在新增或者编辑内容的时候的数据,比如下面只显示指定部门的员工"""

print(db_field.name)

if not self.request.user.is_superuser:

# 对case这个表项的下拉框选择进行过滤

if db_field.name == "employee":

kwargs["queryset"] = Employee.objects.filter(dept=self.request.user.dept).order_by('id')

# 对assigned_recipient这个表项的下拉选择进行过滤

return db_field.formfield(**dict(**kwargs))

else:

attrs = self.get_field_attrs(db_field, **kwargs)

return db_field.formfield(**dict(attrs, **kwargs))

def save_models(self):

"""新增或者修改保存数据的时候调用,可以在保存之前修改数据内容或者添加其它只读字段的内容"""

self.new_obj.operator=self.request.user

super().save_models()

def post(self, request, *args, **kwargs):

"""在点击提交保存按钮的时候触发,可以对数据进行一个校验"""

#print(request.POST)

if request.POST.get('action') not in ['delete_selected']:

err_tip=''

jf=RulesRecord.objects.filter(id=request.POST.get('jf')).first()

#print(jf.person_limit,jf.date_limit,jf.times_limit,jf.jf_num,jf.jf_num_max)

if jf.person_limit=='每人':

if jf.date_limit=='不限':

exists_count=JFLogs.objects.filter(employee_id=request.POST.get('employee'),jf_id=request.POST.get('jf')).count()

if exists_count>=jf.times_limit:

err_tip="个人奖励次数已到达次数上限"

elif jf.date_limit=='每天':

start_date = datetime.datetime(datetime.datetime.now().year, datetime.datetime.now().month, datetime.datetime.now().day,0,0,0)

end_date = datetime.datetime(datetime.datetime.now().year, datetime.datetime.now().month, datetime.datetime.now().day,23,59,59)

#print(start_date,end_date)

exists_count=JFLogs.objects.filter(employee_id=request.POST.get('employee'),jf_id=request.POST.get('jf')).filter(inserttime__range=(start_date,end_date)).count()

#print(exists_count)

if exists_count>=jf.times_limit:

err_tip="个人奖励次数已到达每天上限"

elif jf.date_limit=='每周':

monday,sunday=get_current_week()

start_date = datetime.datetime(monday.year, monday.month, monday.day,0,0,0)

end_date = datetime.datetime(sunday.year, sunday.month, sunday.day,23,59,59)

exists_count=JFLogs.objects.filter(employee_id=request.POST.get('employee'),jf_id=request.POST.get('jf')).filter(inserttime__range=(start_date,end_date)).count()

#print(exists_count)

if exists_count>=jf.times_limit:

err_tip="个人奖励次数已到达每周上限"

else:

err_tip='未知错误'

elif jf.person_limit=='每部门':

dept=Employee.objects.filter(id=request.POST.get('employee')).first()

emps=Employee.objects.filter(dept=dept.dept).values("id")

#print(emps)

if jf.date_limit=='不限':

exists_count=JFLogs.objects.filter(employee_id__in=emps,jf_id=request.POST.get('jf')).count()

if exists_count>=jf.times_limit:

err_tip="部门奖励次数已到达上限"

elif jf.date_limit=='每天':

start_date = datetime.datetime(datetime.datetime.now().year, datetime.datetime.now().month, datetime.datetime.now().day,0,0,0)

end_date = datetime.datetime(datetime.datetime.now().year, datetime.datetime.now().month, datetime.datetime.now().day,23,59,59)

#print(start_date,end_date)

exists_count=JFLogs.objects.filter(employee_id__in=emps,jf_id=request.POST.get('jf')).filter(inserttime__range=(start_date,end_date)).count()

#print(exists_count)

if exists_count>=jf.times_limit:

err_tip="部门奖励次数已到达每天上限"

elif jf.date_limit=='每周':

monday,sunday=get_current_week()

start_date = datetime.datetime(monday.year, monday.month, monday.day,0,0,0)

end_date = datetime.datetime(sunday.year, sunday.month, sunday.day,23,59,59)

exists_count=JFLogs.objects.filter(employee_id__in=emps,jf_id=request.POST.get('jf')).filter(inserttime__range=(start_date,end_date)).count()

#print(exists_count)

if exists_count>=jf.times_limit:

err_tip="部门奖励次数已到达每周上限"

else:

err_tip='未知错误'

if err_tip:

messages.add_message(request, messages.ERROR, err_tip)

return HttpResponseRedirect('/xadmin/frontapp/jflogs/add/')

else:

obj=Employee.objects.filter(id=request.POST.get('employee')).first()

obj.jf_num+=int(request.POST.get('jf_num'))

obj.save()

return super(JFLogsAdmin, self).post(request, args, kwargs)

else:

if request.POST.get('post')=='yes':

print(request.POST)

idx=[int(x) for x in request.POST.getlist('_selected_action')]

print(idx)

jfs=JFLogs.objects.filter(id__in=idx)

for jf in jfs:

obj=Employee.objects.filter(id=jf.employee_id).first()

obj.jf_num-=jf.jf_num

if obj.jf_num<0:obj.jf_num=0

obj.save()

return super(JFLogsAdmin, self).post(request, args, kwargs)

14、书签的使用

以下是官方书签的示例,可以看到大概就是可以设置书签名称、和过滤条件。

class UserAdmin(object):

list_bookmarks = [{

'title': "书签名称", # 书签的名称, 显示在书签菜单中

'query': {'gender': True,'postdate__gte':20200327}, # 过滤参数, 是标准的 queryset 过滤

'order': ('-age','name'), # 排序参数

'cols': ('first_name', 'age', 'phones'), # 显示的列

'search': 'Tom' # 搜索参数, 指定搜索的内容

}, {...}

]

如何一打开就使用默认书签呢?我是这么做的:

1、修改\xadmin\plugins\bookmark.py文件,增加一个selected判断(大概是84行)

#修改前

selected = (current_qs == bk_qs)

#修改后

if not current_qs and 'selected' in bk:

selected=bk['selected']

current_qs = bk_qs

else:

selected = (current_qs == bk_qs)

2、然后配合adminx.py里面的list_bookmarks设置,增加selected参数

list_bookmarks = [{

'title': "书签名称", # 书签的名称, 显示在书签菜单中

'query': {'gender': True,'postdate__gte':20200327}, # 过滤参数, 是标准的 queryset 过滤

'selected':True

},]

3、当然,默认查询的queryset也要增加一个默认过滤条件

class NewsAdmin(object):

model_icon='fa fa-tasks'

list_display=['classify','postdate','title','go_to']

...

list_bookmarks = [{

'title': "今天新闻", # 书签的名称, 显示在书签菜单中

'query': {'postdate__exact': datetime.datetime.now().strftime('%Y%m%d')}, # 过滤参数, 是标准的 queryset 过滤

'order': ('classify','-postdate','orirank'), # 排序参数

'selected':True,

},

{

'title': "近两天新闻", # 书签的名称, 显示在书签菜单中

'query': {'postdate__gte': (datetime.datetime.now()+datetime.timedelta(-1)).strftime('%Y%m%d')}, # 过滤参数, 是标准的 queryset 过滤

'order': ('classify','-postdate','orirank'), # 排序参数

},

]

class Meta:

verbose_name="新闻"

verbose_name_plural=verbose_name

def queryset(self):

fillters={}

for k in self.request.GET.keys():

if '_p_' in k:

fillters[k.replace('_p_','')]=self.request.GET.get(k)

if not fillters:

fillters={'postdate__exact': datetime.datetime.now().strftime('%Y%m%d')} #如果没有选择标签就要增加一个默认的过滤条件

qs = super(NewsAdmin, self).queryset()

qs=qs.filter(**fillters)

return qs

==============2020-04-21更新==============

在导出数据的时候指定导出字段

1、修改extra_apps\xadmin\plugins\export.py的get_result_list方法

def get_result_list(self, __):

if self.request.GET.get('all', 'off') == 'on':

self.admin_view.list_per_page = sys.maxsize

#增加下面这一行

self.admin_view.list_display=getattr(self.admin_view,'list_export_fields', self.admin_view.list_display)

return __()

2、在admin.py或者xadmin.py中增加list_export_fields字段即可

xadmin中写ajax,xadmin使用笔记相关推荐

  1. xadmin中写ajax,xadmin入门使用

    Django的xadmin是和admin相类似的管理后台,里面的很多方法都是一样的,只不过导入的类不一样,个人感觉xadmin的功能更加强大(主要是适合我现在写的东西) 下边就来一些使用的小示例: i ...

  2. xadmin中写ajax,关于xadmin后台下拉框修改为ajax模糊搜索问题

    在xadmin后台添加课程页面要关联org,默认是下拉框,视频13-3里面有个地方讲可以把下拉框修改为通过ajax方式展示, 我具体方式如下: class CourseOrgAdmin(object) ...

  3. 在a标签中写ajax,ajax请求后的数据渲染到页面中,a链接失效

    ¥ ¥ 点击购买 利用template 渲染后的数据 为什么a链接点击无法跳转 使用mui框架 在手机上测试 css样式 less写的 ul { li { float: left; width: ~& ...

  4. vscode中写markdown格式笔记的配置过程和相关语法

    vscode中写markdown格式笔记的配置过程和相关语法 一.引言 二.安装相关插件 三.开始使用vscode进行编写 四.相关语法 参考链接: link link 一.引言 以前使用 Typor ...

  5. 自己学习c++过程中写下的笔记,只做基础了解使用

    01书写helloworld #include <iostream> using namespace std;int main() {cout << "Hello W ...

  6. tp框架里怎么写ajax,TP中的ajax请求

    以jQuery中的ajax为例: (1)引入jQuery 通过模板替换表示路径,我们可以自定义模板替换变量(在config中定义) /*自定义模板替换标签*/ 'TMPL_PARSE_STRING' ...

  7. 帝君级别 纯手写 原创 jQuery入门笔记

    帝君级别 纯手写 原创 jQuery入门笔记 广治君今天下午整理了一下jQuery的入门学习思路,以及学习内容 一.学习jQuery的目的 为什么要学习jQuery,低程度的一定是你在学前端或者后端, ...

  8. 第 4 章:Vue 中的 ajax

    学习资料来自尚硅谷VUE教学视频 csdn:课程代码.vue3笔记.课件 gitee:课件.代码.资料 其他:vscode插件推荐.第三方库网站.npmjs库 工具库推荐: moment.js 时间处 ...

  9. [DWR(Ajax)]DWR使用笔记

    [DWR(Ajax)]DWR使用笔记 把老师发的文档转载分享一下. DWR是一个框架,简单的说就是能够在javascript直接调用java方法,而不必去写一大堆的javascript代码.它的实现是 ...

最新文章

  1. 为什么Rust连续4年获“最受喜爱编程语言”?
  2. R语言绘制环形树状图
  3. Linux内核常见FAQ
  4. 面试系列-SpringMVC那些事(一)
  5. Redis的简介与安装
  6. 三、数据分析前,打下数据处理基础(下)
  7. 【MySQL】 如何在“海啸”下保命
  8. java 注解入门 简书_Java基础-注解
  9. python log模块
  10. 使用邮件客户端整合日常信息
  11. 一位财务自由人士的投资修行
  12. Ace Admin安装配置教程
  13. 帝国CMS文章内容超级伪静态 去除栏目id 以自定义英文名称和ID组成
  14. 实习周记----第三周
  15. PNG格式小图标的CSS任意颜色赋色技术
  16. Dexpot 虚拟桌面软件(推荐)
  17. android 适配红米,小米MIUI放出Android Q适配计划,11款手机参与,包括红米Note 7
  18. 计算机二级能加综合测评,2016综合测评加分细则.doc
  19. 电脑显示器突然变了颜色
  20. 安装rabbitMQ踩的坑

热门文章

  1. java io -- FileInputStream
  2. matlab仿真参考文献,生成算法论文,关于AOS自相似业务流等时帧生成算法的Matlab仿真相关参考文献资料-免费论文范文...
  3. Android ImageView扩展 支持本地gif图片 支持网络gif图片
  4. 网页访问速度慢?用HTTrack自己制作一个镜像网站吧
  5. 惠普计划未来3年裁员2.46万人 年节省$18亿
  6. 搭建邮件服务器过程,关于服务器:搭建邮件服务器过程非常简单
  7. 如何进行安全技术交底
  8. OPhone应用开发权威指南
  9. 用python爬取动态网页上的图片(百度图片)
  10. 常用js正则表达式 Javascript正则表达式实战手册