01-下载源码 安装
https://github.com/sshwsfc/xadmin
Install
Xadmin is best installed via PyPI. To install the latest version, run:
pip install xadmin
or Install from github source:
pip install git+git://github.com/sshwsfc/xadmin.git
Install from github source for Django 2.0:
pip install git+git://github.com/sshwsfc/xadmin.git@django2
https://github.com/sshwsfc/xadmin/tree/django2 打开github,找到xadmin源码,点击branch,然后选择django2版本,全新的已经变成前端了,clone or download
把zip文件放到pip目录下,运行下面命令安装:
pip install xadmin-django2
*********************************************************************************************************
(venv) D:\zz\PycharmProjects\output\venv\Lib\site-packages>pip install xadmin-django2.zip
(venv) D:\zz\PycharmProjects\output\venv\Lib\site-packages>pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xadmin-django2.zip
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Processing d:\zz\pycharmprojects\output\venv\lib\site-packages\xadmin-django2.zip
Requirement already satisfied: setuptools in c:\python\python37\lib\site-packages (from xadmin==2.0.1) (39.0.1)
Requirement already satisfied: django>=2 in c:\python\python37\lib\site-packages (from xadmin==2.0.1) (2.1.1)
Collecting django-crispy-forms>=1.6.0
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/c5/1e/166304128017b1dc45c6b79af753af93f6a0939c7ecca4258ca573aed8cd/django_crispy_forms-1.9.0-py2.py3-none-any.whl (107 kB)
|████████████████████████████████| 107 kB 819 kB/s
Collecting django-reversion>=2.0.0
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/d9/c2/67e6fd0b67e1283e7608e5798ba5e78c842a0e25af80038d4913cf0d18ea/django_reversion-3.0.7-py3-none-any.whl (84 kB)
|████████████████████████████████| 84 kB 694 kB/s
Collecting django-formtools>=1.0
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/16/2b/f2dc15cf7fb830bf22ec87739786ca7633902474edd7cdb9c52a56434ed2/django_formtools-2.2-py2.py3-none-any.whl (148 kB)
|████████████████████████████████| 148 kB 2.2 MB/s
Collecting django-import-export>=0.5.1
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/ad/a0/f7da2f39dfcbb6e0416ab0803900bec3797b3013cb7d2737dbd91221316d/django_import_export-2.0.2-py3-none-any.whl (82 kB)
|████████████████████████████████| 82 kB 142 kB/s
Collecting httplib2==0.9.2
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/ff/a9/5751cdf17a70ea89f6dde23ceb1705bfb638fd8cee00f845308bf8d26397/httplib2-0.9.2.tar.gz (205 kB)
|████████████████████████████████| 205 kB 6.8 MB/s
Collecting future
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/45/0b/38b06fd9b92dc2b68d58b75f900e97884c45bedd2ff83203d933cf5851c9/future-0.18.2.tar.gz (829 kB)
|████████████████████████████████| 829 kB 6.4 MB/s
Requirement already satisfied: six in c:\python\python37\lib\site-packages (from xadmin==2.0.1) (1.11.0)
Requirement already satisfied: pytz in c:\python\python37\lib\site-packages (from django>=2->xadmin==2.0.1) (2018.5)
Collecting tablib[html,ods,xls,xlsx,yaml]>=0.14.0
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/7b/68/6ebc32ee79945feac078713f3fe3dc280f328d10d178674dc1227ade8d01/tablib-1.1.0-py3-none-any.whl (47 kB)
|████████████████████████████████| 47 kB 2.1 MB/s
Collecting diff-match-patch
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/f0/2a/5ba07def0e9107d935aba62cf632afbd0f7c723a98af47ccbcab753d2452/diff-match-patch-20181111.tar.gz (58 kB)
|████████████████████████████████| 58 kB 1.0 MB/s
Collecting markuppy; extra == "html"
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/4e/ca/f43541b41bd17fc945cfae7ea44f1661dc21ea65ecc944a6fa138eead94c/MarkupPy-1.14.tar.gz (6.8 kB)
Collecting odfpy; extra == "ods"
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/97/73/8ade73f6749177003f7ce3304f524774adda96e6aaab30ea79fd8fda7934/odfpy-1.4.1.tar.gz (717 kB)
|████████████████████████████████| 717 kB 6.4 MB/s
Collecting xlrd; extra == "xls"
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/b0/16/63576a1a001752e34bf8ea62e367997530dc553b689356b9879339cf45a4/xlrd-1.2.0-py2.py3-none-any.whl (103 kB)
|████████████████████████████████| 103 kB 6.4 MB/s
Collecting xlwt; extra == "xls"
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/44/48/def306413b25c3d01753603b1a222a011b8621aed27cd7f89cbc27e6b0f4/xlwt-1.3.0-py2.py3-none-any.whl (99 kB)
|████████████████████████████████| 99 kB 2.4 MB/s
Collecting openpyxl>=2.4.0; extra == "xlsx"
Using cached https://pypi.tuna.tsinghua.edu.cn/packages/95/8c/83563c60489954e5b80f9e2596b93a68e1ac4e4a730deb1aae632066d704/openpyxl-3.0.3.tar.gz (172 kB)
Requirement already satisfied: pyyaml; extra == "yaml" in c:\python\python37\lib\site-packages (from tablib[html,ods,xls,xlsx,yaml]>=0.14.0->django-import-export>=0.5.1->xadmin==2.0.1) (
5.1.2)
Collecting defusedxml
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/06/74/9b387472866358ebc08732de3da6dc48e44b0aacd2ddaa5cb85ab7e986a2/defusedxml-0.6.0-py2.py3-none-any.whl (23 kB)
Collecting jdcal
Using cached https://pypi.tuna.tsinghua.edu.cn/packages/f0/da/572cbc0bc582390480bbd7c4e93d14dc46079778ed915b505dc494b37c57/jdcal-1.4.1-py2.py3-none-any.whl (9.5 kB)
Collecting et_xmlfile
Using cached https://pypi.tuna.tsinghua.edu.cn/packages/22/28/a99c42aea746e18382ad9fb36f64c1c1f04216f41797f2f0fa567da11388/et_xmlfile-1.0.1.tar.gz (8.4 kB)
Installing collected packages: django-crispy-forms, django-reversion, django-formtools, markuppy, defusedxml, odfpy, xlrd, xlwt, jdcal, et-xmlfile, openpyxl, tablib, diff-match-patch, dj
ango-import-export, httplib2, future, xadmin
Running setup.py install for markuppy ... done
Running setup.py install for odfpy ... done
Running setup.py install for et-xmlfile ... done
Running setup.py install for openpyxl ... done
Running setup.py install for diff-match-patch ... done
Running setup.py install for httplib2 ... done
Running setup.py install for future ... done
Running setup.py install for xadmin ... done
Successfully installed defusedxml-0.6.0 diff-match-patch-20181111 django-crispy-forms-1.9.0 django-formtools-2.2 django-import-export-2.0.2 django-reversion-3.0.7 et-xmlfile-1.0.1 future
-0.18.2 httplib2-0.9.2 jdcal-1.4.1 markuppy-1.14 odfpy-1.4.1 openpyxl-3.0.3 tablib-1.1.0 xadmin-2.0.1 xlrd-1.2.0 xlwt-1.3.0
**********************************************************或者更换安装源(使用豆瓣源)
pip install -i https://pypi.douban.com/simple xadmin-django2.zip
由于使用的是Django2.0的版本,所以需要安装xadmin项目django2分支的代码。
在PyCharm里打开命令行工具,输入以下命令完成安装:
pip install git+git://github.com/sshwsfc/xadmin.git@django2
也可以使用https的地址安装,命令如下:
pip install git+https://github.com/sshwsfc/xadmin.git@django2
安装成功后,同时也安装了很多依赖的包。
为了主题和全局配置,需要导入views
- 1、项目中新建目录 extra_apps (名称可自定义),作为第三方依赖的存放目录
- 2、选中 extra_apps 目录,右击Mark Directory as > Resource Root
-
配置项目 setting 新增搜索目录 extra_apps
STATIC_URL = '/static/' STATIC_ROOT = 'APP/static' STATICFILES_DIRS = ( os.path.join(BASE_DIR,"APP/static/html"), os.path.join(BASE_DIR, 'extra_apps'),)
02-配置settings.py
settings.py文件
INSTALLED_APPS中添加xadmin的安装
INSTALLED_APPS = (
...
'xadmin',
'crispy_forms',
'reversion',
...
)
# 修改使用中文界面
LANGUAGE_CODE = 'zh-Hans'
# 修改时区
TIME_ZONE = 'Asia/Shanghai'
ALLOWED_HOSTS = ['*', ]
03-配置路由
urls.py文件
urls里面要添加xadmin的匹配,示例如下:
import xadmin
path('xadmin/', xadmin.site.urls),
或者更详细的配置
# urls.py
# -*- coding: utf-8 -*-
# from django.conf.urls import include, url
from django.urls import include, path
# Uncomment the next two lines to enable the admin:
import xadmin
xadmin.autodiscover()
# version模块自动注册需要版本控制的 Model
from xadmin.plugins import xversion
xversion.register_models()
from django.contrib import admin
urlpatterns = [
path(r'xadmin/', xadmin.site.urls)
]
04-创建数据库
python manage.py makemigrations
python manage.py migrate
05-创建超级用户
python manage.py createsuperuser
06-拉取静态文件到本地
python manage.py collectstatic
07-站点Model管理
xadmin 可以使用的页面样式控制基本与Django原生的admin一直。
list_display 列表展示的字段
preserve_filters 默认情况下,当你对目标进行创建、编辑或删除操作后,页面会依然保持原来的过滤状态。将preserve_filters设为False后,则会返回未过滤状态。
prepopulated_fields 设置预填充字段。不接收DateTimeField、ForeignKey和ManyToManyField类型的字段。
view_on_site 这个属性可以控制是否在admin页面显示“View site”的链接。这个链接主要用于跳转到你指定的URL页面。
free_query_filter 属性: 默认为 True , 指定是否可以自由搜索. 如果开启自由搜索, 用户可以通过 url 参数来进行特定的搜索,
search_fields 可以通过搜索框搜索的字段名称,xadmin使用的是 模糊查询,存在外键 同 list_filter 一样 注意:只能包括 字符类型,不能有 非字符类型 如:SBBH-20180515-0002
list_filter 可以进行过滤操作的列,例如:存在外键字段class ---》student__class 获取值
ordering 默认排序的字段
readonly_fields 在编辑页面的只读字段
exclude 在编辑页面隐藏的字段
list_editable 在列表页可以快速直接编辑的字段
show_detail_fileds 在列表页显示详情信息
refresh_times 指定列表页的数据定时刷新 例如:refresh_times=(3,5)
list_export 控制列表页导出数据的类型
show_bookmarks 控制是否显示书签功能
data_charts 控制显示图标的样式
model_icon 配置表的图标,可以在 awesome 上下载最新的font-awesome.css 替换,并寻找相应的icon书写
fieldsets ,详细页面时,使用fieldsets标签对数据进行分割显示
empty_value_display = "列数据为空时,显示默认值"
# 列聚合,可用的值:"count","min","max","avg", "sum"
aggregate_fields = {"expire": "max"}
# 显示还原按钮,删除修改的信息可以还原
reversion_enable = True
# 添加数据时候,一步一步提供数据
wizard_form_list = [
("基础信息", ("name", "contact", "telphone", "address")),
("其它信息", ("customer_id", "expire", "description")),
]
fields 表单显示内容, 不包含在内的字段不能编辑
filter_horizontal 从‘多选框’的形式改变为‘过滤器’的方式,水平排列过滤器,必须是一个 ManyToManyField类型,且不能用于 ForeignKey字段,默认地,管理工具使用下拉框 来展现外键 字段
raw_id_fields 将ForeignKey字段从‘下拉框’改变为‘文本框’显示
relfield_style 后台自定义不是下拉选择框,而是搜索框(解决了为什么用户不是下拉框的问题。。) relfield_style = 'fk-ajax'
exclude 在编辑和查看列表时指定不显示的字段
list_editable 列表显示的时候,指定的字段可以直接页面一键编辑
list_display_links 设置默认可编辑字段
list_per_page = 20 每页显示20个
actions = ('ocr_action', 'excel_action', 'auto_excel_action') 在类中自定义的函数方法
auto_excel_action.short_description='自动化导入数据文件' 函数名描述
object_list_template = "test.html" 自定义页面
data_charts 图表,该属性为dict类型,key为图表的标示名称,value为图表的具体设置属性
data_charts = {
"user_count": {'title': u"约运动",
"x-field": "sport_time",
"y-field": ("people_nums",),
},
}
图表属性:
title : 图表的显示名称
x-field : 图表的 X 轴数据列, 一般是日期, 时间等
y-field : 图表的 Y 轴数据列, 该项是一个 list, 可以同时设定多个列, 这样多个列的数据会在同一个图表中显示
order : 排序信息, 如果不写则使用数据列表的排序
# 导出类型
list_export = ('xls', 'xml', 'json') list_export设置为None来禁用数据导出功能
#导出字段
list_export_fields = ('start_people', 'sport', 'sport_time')
08-站点的全局配置
# settingx/adminx.py
import xadmin
from xadmin import viewsclass
class BaseSetting(object):
"""xadmin的基本配置"""
enable_themes = True # 开启主题切换功能
use_bootswatch = True # 支持切换主题
xadmin.site.register(views.BaseAdminView, BaseSetting)
class GlobalSettings(object):
"""xadmin的全局配置"""
site_title = "xxx后台管理系统" # 设置站点标题
site_footer = "xxxxxxx" # 设置站点的页脚
menu_style = "accordion" # 设置菜单折叠,在左侧,默认的
# 设置models的全局图标, UserProfile, Sports 为表名
global_search_models = [UserProfile, Sports]
global_models_icon = {
UserProfile: "glyphicon glyphicon-user", Sports: "fa fa-cloud"
xadmin.site.register(views.CommAdminView, GlobalSettings)
09-app名称的修改
# app名为users下的apps.py
from django.apps import AppConfig
class UsersConfig(AppConfig):
# 设置app图标
app_icon = 'fa fa-line-chart'
# app名
name = 'users'
verbose_name = u'用户管理'
# __init__.py
default_app_config='users.apps.UsersConfig'
10-自定义导航菜单顺序
from xadmin import views
class GlobalSetting(object):
def get_site_menu(self):
return (
{'title': '课程管理', 'menus': (
{'title': '课程信息', 'url': self.get_model_url(Course, 'changelist')},
{'title': '章节信息', 'url': self.get_model_url(Lesson, 'changelist')},
{'title': '视频信息', 'url': self.get_model_url(Video, 'changelist')},
{'title': '课程资源', 'url': self.get_model_url(CourseResource, 'changelist')},
{'title': '课程评论', 'url': self.get_model_url(CourseComments, 'changelist')},
)},
{'title': '机构管理', 'menus': (
{'title': '所在城市', 'url': self.get_model_url(CityDict, 'changelist')},
{'title': '机构讲师', 'url': self.get_model_url(Teacher, 'changelist')},
{'title': '机构信息', 'url': self.get_model_url(CourseOrg, 'changelist')},
)},
{'title': '用户管理', 'menus': (
{'title': '用户信息', 'url': self.get_model_url(UserProfile, 'changelist')},
{'title': '用户验证', 'url': self.get_model_url(EmailVerifyRecord, 'changelist')},
{'title': '用户课程', 'url': self.get_model_url(UserCourse, 'changelist')},
{'title': '用户收藏', 'url': self.get_model_url(UserFavorite, 'changelist')},
{'title': '用户消息', 'url': self.get_model_url(UserMessage, 'changelist')},
)},
{'title': '系统管理', 'menus': (
{'title': '用户咨询', 'url': self.get_model_url(UserAsk, 'changelist')},
{'title': '首页轮播', 'url': self.get_model_url(Banner, 'changelist')},
{'title': '用户分组', 'url': self.get_model_url(Group, 'changelist')},
{'title': '用户权限', 'url': self.get_model_url(Permission, 'changelist')},
{'title': '日志记录', 'url': self.get_model_url(Log, 'changelist')},
)},
xadmin.site.register(views.CommAdminView, GlobalSetting)
11-设置只读字段
在使用xadmin的时候,ModelAdmin默认只有对于model的增删改查,但是总是有些字段是不希望用户来编辑的。而 readonly_fields 设置之后不管是admin还是其他用户都会变成只读,而我们通常只是想限制普通用户。 这时我们就可以通过重写 get_readonly_fields 方法来实现对特定用户的只读显示。
class UserInfoAdmin():
def get_readonly_fields(self, **kwargs):
""" 重新定义此函数,限制普通用户所能修改的字段 """
print(self.org_obj)
if self.user.is_superuser:
self.readonly_fields = []
return self.readonly_fields
readonly_fields = ('user_email',)
12-在list_display显示自定义函数:
list_display = ['get_chapter_num']
# 需要在自定义的函数下加上如下内容
def get_chapter_num(self):
return self.chapter_set.all().count()
get_chapter_num.short_description= '章节数'
13-设置页面跳转,需自定义函数
# 定义自定义的一个跳转字段, 内部为html代码的形式
def go_to(self):
from django.utils.safestring import mark_safe
return mark_safe("<a href='http://wwww.baidu.com'>跳转</a>")
go_to.short_description = "跳转"
14、如果想添加数据的同时方便添加关联model:inlines 机制 同一个页面 可以添加 所有的相关信息
class ChapterInline:
model = Chapter
extra = 0
在CoursesXadmin 添加 inlines = [ChapterInline]
15-重载显示样式
from xadmin.layout import Main,Fieldset,Row,Side
def get_form_layout(self):
if self.org_obj:
self.form_layout = (
Main(
Fieldset('',
'username', 'password',
css_class='unsort no_title'
),
Fieldset(_('Personal info'),
Row('first_name', 'last_name'), # 显示在一行
'email'
),
Fieldset(_('Permissions'),
'groups', 'user_permissions'
),
Fieldset(_('Important dates'),
'last_login', 'date_joined'
),
),
Side(
Fieldset(_('Status'),
'is_active', 'is_staff', 'is_superuser',
),
)
)
return super(UserAdmin, self).get_form_layout()子主题
16-model的管理器,一个model 分不同情况 管理
class Course(models.Model):
pass
class BannerCourse(Course): # 继承 父类 course
class Meta:
verbose_name = '轮播课程'
verbose_name_plural = verbose_name
proxy = True # 不会生成新的表
# 注册新的表
class CourseSourceAdmin(object):
list_display = ['course', 'name', 'add_time', 'download']
list_filter = ['course', 'name', 'add_time', 'download']
search_fields = ['course', 'name', 'download']
def queryset(self):
qs = super(CourseAdmin, self).queryset()
qs = qs.filter(is_banner=False)
return qs
17-获取当前的user表model
from django.contrib.auth import get_user_model (获取当前的user表model)
User = get_user_model()
site.register(User,Useradmin)
18-卸载注册的model
from django.contrib.auth.models import User
xadmin.site.unregister(User)
19-替换默认的注册 user(继承了abstractuser)
class UserInfoAdmin(object):
list_display = ['auth', 'name', 'depart', 'email', 'username']
list_filter = ['auth', 'name', 'depart', 'email', 'username']
search_fields = ['auth', 'name', 'depart', 'email', 'username']
list_editable = ['auth', 'name', 'depart', 'email', 'username']
list_display_links = ['auth', 'name', 'depart', 'email', 'username']
model_icon = 'fa fa-user-circle-o'
from django.contrib.auth import get_user_model # 获取当前的user_model
xadmin.site.unregister(get_user_model()) # 注销 user
xadmin.site.register(UserInfo,UserInfoAdmin) # 注册新的 user
20-表单根据用户显示不同的字段内容 get_model_form
import xadmin
# Register your models here.
from .models import User
from xadmin.plugins import auth
class UserAdmin(auth.UserAdmin):
list_display = ['id', 'username', 'mobile', 'email', 'date_joined']
readonly_fields = ['last_login', 'date_joined']
search_fields = ('username', 'first_name', 'last_name', 'email', 'mobile')
style_fields = {'user_permissions': 'm2m_transfer', 'groups': 'm2m_transfer'}
# 表单根据用户显示不同的字段内容
def get_model_form(self, **kwargs):
if self.org_obj is None:
self.fields = ['username', 'mobile', 'is_staff']
return super().get_model_form(**kwargs)
xadmin.site.unregister(User)
xadmin.site.register(User, UserAdmin)
而在 admin 里是 get_fields
# 表单根据用户显示不同的字段内容
def get_fields(self, request, obj=None):
21-模型编辑页面Field分区显示--form_layout
在admin.py中我们可以通过Fieldsets去设置字段的分块显示,例如以下代码:
界面显示会上下分区,分为名字为空和名字为其它的两个区域。
class DeviceAdmin(admin.ModelAdmin):
...
fieldsets = (
(None, {
'fields': ('site', 'device_name', 'device_id', 'device_type', 'account', 'password')
}),
('其它', {
'fields': ('responsible_by', 'device_ip', 'device_model', 'sn_number', 'supplier', 'buy_date', 'expire_date', 'note', 'attachment', 'date'),
}),
)
而在xadmin.py中,这个字段不再生效,需用form_layout去设置。
可分为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'),
)
)
22-获取用户信息并填充模型字段--save_models
有时模型中会需要记录添加数据的用户,保存在created_by这样的字段中。这时我们就需要重写save_model方法,在保存模型时存入用户的信息。
admin.py中会sava_model,如下。
class DeviceAdmin(admin.ModelAdmin):
...
def save_model(self, request, obj, form, change):
obj.area_company = Group.objects.get(user=request.user)
super().save_model(request, obj, form, change)
而xadmin.py中改为使用save_models。
class DeviceAdmin(object):
...
def save_models(self):
obj = self.new_obj
self.new_obj.area_company = Group.objects.get(user=self.request.user)
super().save_models()
23-根据登录用户或组过滤数据--queryset
需要根据登录用户或组过滤数据时,admin.py中是重写get_queryset方法,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))
24-外键下拉框添加过滤
admin.py中发现将site字段添加到autocomplete_fields(autocomplete_fields作用是下拉选项会多出一个搜索框,方便搜索选择)之后,会自动进行过滤,满足上述场景要求。如果不使用autocomplete_fields,可以通过重写formfield_for_foreignkey方法去做筛选。如下:
class DeviceAdmin(admin.ModelAdmin):
...
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if not self.request.user.is_superuser: # 非superuser进行过滤,superuser可以看到全部
if db_field.name == "site":
kwargs["queryset"] = Site.objects.filter(area_company=Group.objects.get(user=self.request.user))
return super(DeviceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
而xadmin.py中没有这个方法了,需要重写formfield_for_dbfield方法。如下:
class DeviceAdmin(object):
...
def formfield_for_dbfield(self, db_field, **kwargs):
if not self.request.user.is_superuser:
if db_field.name == "site":
kwargs["queryset"] = Site.objects.filter(area_company=Group.objects.get(user=self.request.user))
return super(DeviceAdmin, self).formfield_for_dbfield(db_field, **kwargs)
25 django自带的admin是有save_models和delete_model的,后台修改模型类后就会执行改函数,xadmin中如下
def save_models(self):
# 新的对象
obj = self.new_obj
# 可以在这里面写些逻辑
# 保存该对象
obj.save()
def delete_model(self):
# 删除数据对象
obj = self.obj
# 相应的操作
obj.delete()
26 定制HTML模板
add_form_template = None
change_form_template = None
change_list_template = None
delete_confirmation_template = None
delete_selected_confirmation_template = None
object_history_template = None
27 xadmin此版本貌似不能加载views.py
作为破解在 __init__.py中增加了 import views一行,如下:
__init__.py
import views
28、列表视图新增自定义按钮
https://www.cnblogs.com/Tommy-Yu/p/5443127.html
http://www.cnblogs.com/livingintruth/p/3738601.html
29-自定义actions
1. 首先要创建一个 Action 类, 该类需要继承 BaseActionView. BaseActionView 是 ModelAdminView 的子类:
from xadmin.plugins.actions import BaseActionView
class MyAction(BaseActionView):
# 这里需要填写三个属性
action_name = "my_action" #: 相当于这个 Action 的唯一标示, 尽量用比较针对性的名字
description = _(u'Test selected %(verbose_name_plural)s') #: 描述, 出现在 Action 菜单中, 可以使用 ``%(verbose_name_plural)s`` 代替 Model 的名字.
model_perm = 'change' #: 该 Action 所需权限
# 而后实现 do_action 方法
def do_action(self, queryset):
# queryset 是包含了已经选择的数据的 queryset
for obj in queryset:
# obj 的操作
...
# 返回 HttpResponse
return HttpResponse(...)
2. 然后在 Model 的 OptionClass 中使用这个 Action:
class MyModelAdmin(object):
actions = [MyAction, ]
3. 这样就完成了自己的 Action。
30给这个方法添加一个boolean的属性并赋值为True,它将显示为on/off的图标
from django.db import models
from django.contrib import admin
class Person(models.Model):
first_name = models.CharField(max_length=50)
birthday = models.DateField()
def born_in_fifties(self):
return self.birthday.strftime('%Y')[:3] == '195'
# 关键在这里
born_in_fifties.boolean = True
class PersonAdmin(admin.ModelAdmin):
# 官方文档这里有错,将'name'改为'first_name'
list_display = ('first_name', 'born_in_fifties')
31、屏蔽界面的添加按钮
32、xadmin列表页添加自定义工具栏toolbar
https://blog.csdn.net/iteye_12715/article/details/82678755
33-想对某些字段设置颜色,可用下面的设置
from django.db import models
from django.contrib import admin
from django.utils.html import format_html
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
color_code = models.CharField(max_length=6)
def colored_name(self):
return format_html(
'<span style="color: #{};">{} {}</span>',
self.color_code,
self.first_name,
self.last_name,
)
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'colored_name')
34、菜单分组管理
https://www.cnblogs.com/fiona-zhong/p/9647986.html
35、增加页面显示的列 ‘跳转’——显示自定义的html代码
# models.py
class Course(models.Model):
.
.
.
def go_to(self):
from django.utils.safestring import mark_safe
#mark_safe后就不会转义
return mark_safe("<a href='https://home.cnblogs.com/u/derek1184405959/'>跳转</a>")
go_to.short_description = "跳转"
# adminx.py
class CourseAdmin(object):
list_display = ['go_to']
效果如下:
36、xadmin主页布局的修改
例如:
数据库是 MySQL,xadmin自带的两张表:xadmin_usersettings、xadmin_userwidget
xadmin_usersettings:字段value的初始值应为 | ,代表将主页面分为两列。
xadmin_userwidget:记录当前登录用户主页面 显示的小组件。
xadmin/views/dashboard.py部分源码
37、设置xadmin新用户主页的默认布局
数据库:
# xadmin/model.py
@python_2_unicode_compatible
class UserSettings(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_(u"user"))
key = models.CharField(_('Settings Key'), max_length=256)
value = models.TextField(_('Settings Content'))
# 重写save方法
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if not self.value:
self.value = "|"
super(UserSettings, self).save()
page_id = 'home'
default_list = [
[{'list': '{"title": "", "model": "auth.user"}'}, ],
[{'list': '{"title": "", "model": "cashflows.bank_cash_flows"}'}, ],
[{'html': '{"title": "Test Widget", "content": "第一次测试!!"}'}, ],
[{'qbutton': '{"title": "aaa"}'}, ],
]
for i in default_list:
user_widget = UserWidget()
for j in i:
for z in j.keys():
user_widget.page_id = page_id
user_widget.user_id = self.user_id
user_widget.widget_type = z
user_widget.value = j[z]
user_widget.save()
id_list = [] # 存放user的id
a = UserWidget.objects.filter(user_id=self.user)
for i in a:
id_list.append(i.id)
self.value = "%s,%s|%s,%s" % (id_list[0], id_list[1], id_list[2], id_list[3])
UserSettings.objects.filter(user_id=self.user).value = self.value
super(UserSettings, self).save()
else:
super(UserSettings, self).save()
38、admin_order_field
支持查询查找以按相关模型上的值排序。此示例在列表显示中包含“作者名字”列,并允许按名字对其进行排序
https://docs.djangoproject.com/en/1.8/ref/contrib/admin/
39、 获取verbose_name
UserInfo._meta.get_field('name').verbose_name
40、xadmin list_filter 外键显示含有英文,怎么把英文去掉?
# xadmin/plugins/filters.py
# 在这个文件里,第126行
# if len(field_parts) > 1:
# # Add related model name to title
# spec.title = "%s %s" % (field_parts[-2].name, spec.title)
# 注释掉!
41、添加自定义的URL
https://www.cnblogs.com/fangsheng/p/9783245.html
42、xadmin多个model的数据渲染在统一个template中
https://www.cnblogs.com/Tommy-Yu/p/5390555.html
点击add widget 会报错
把这个boundfield.py里面的93行这个代码直接注释掉就可以了
进入xadmin安装路径,编辑C:\Users\administrator\AppData\Local\Programs\Python\Python\Lib\site-packages\django\forms\boundfield.py 第93行注释掉
或者
查找到 xadmin里面的 dashboard.py文件内render方法,增加一个rdnderer默认参数是None
一般路径在 本机虚拟环境\Lib\site-packages\xadmin\views
#render() got an unexpected keyword argument 'renderer'
#修改bug, 添加renderer
#by prism 2018/10/4
def render(self, name, value, attrs=None, renderer=None):