Django使用xadmin管理后台数据

​python学习手册大全点我下载​

作用:xadmin比Django内置的admin更美观、更方便。

一、导入xadmin(第三方库)

方法1、使用pip安装

pip install git+git://github.com/sshwsfc/xadmin.git


方法2、可直接到gitHub上找到xadmin的地址https://github.com/sshwsfc/xadmin 下载到项目根目录 ,然后pip:

pip3 install xadmin-master.zip

安装。

注意:如果使用的Django2.0版本以上的,需要到GitHua上找到xadmin,然后拉取django2的分支。

python框架Django使用xadmin管理后台数据_Django


二、在settings.py里面配置

在注册应用处加上

'xadmin',
'crispy_forms',

python框架Django使用xadmin管理后台数据_Django_02

三、在路由urls.py里面添加路由
import xadmin
urlpatterns = [
url('xadmin/', xadmin.site.urls),
]

python框架Django使用xadmin管理后台数据_Django_03

四、数据迁移
makemigrations
migrate

python框架Django使用xadmin管理后台数据_Django_04

五、建立adminx.py

1、创建adminx.py

2、导入xadmin和model中建立的表模型

from xadmin import views
import xadmin
from .models import User, Candidate

3、添加表管理类,继承于Object

# 基础设置
class BaseSetting(object):
enable_themes = True # 使用主题
use_bootswatch = True

# 全局设置
class GlobalSettings(object):
site_title = '个人网站管理系统' # 标题
site_footer = '个人网站' # 页尾
site_url = '/'
menu_style = 'accordion' # 设置左侧菜单 折叠样式

# 用户的后台管理
class UserAdmin(object):
# 检索字段
search_fields = ['uName','uIP',]
# 要显示的字段
list_display = ['id','uName','uIP' ,'uEmail' ,'uNickName' ,'uGender','uAge' ,'uIcon' ,'isDelete']
# 分组过滤的字段
list_filter = ['uName','uNickName','uGender','uAge','isDelete']
# ordering设置默认排序字段,负号表示降序排序
ordering = ('id',)
# list_per_page设置每页显示多少条记录,默认是100条
list_per_page = 50
# list_editable 设置默认可编辑字段
list_editable = ['uNickName', 'uIcon']
# 候选者的后台管理
class CandidateAdmin(object):
# 检索字段
search_fields = ['cName','cAge','cTimes','cVotes','cPinyin','isDelete',]
# 要显示的字段
list_display = ['id','cName','cAge','cEmail','cDeclaration','cIcon','cTimes','cVotes','cPinyin','isDelete','cVoteType',]
# 分组过滤的字段
list_filter = ['cName','cAge','cTimes','cVotes','cPinyin','isDelete',]
# ordering设置默认排序字段,负号表示降序排序
ordering = ('id',)
# fk_fields 设置显示外键字段
fk_fields = ('cVoteType',)

4、注册表管理类

xadmin.site.register(views.CommAdminView,GlobalSettings)
xadmin.site.register(views.BaseAdminView,BaseSetting)
xadmin.site.register(User,UserAdmin)
xadmin.site.register(Candidate,CandidateAdmin)

python框架Django使用xadmin管理后台数据_Django_05

六、创建管理员
createsuperuser

python框架Django使用xadmin管理后台数据_Django_06

七、效果图

python框架Django使用xadmin管理后台数据_Django_07

python框架Django使用xadmin管理后台数据_Django_08

八、xadmin后台编辑多对多字段

在models.py定义了多对多字段,想要在编辑时可以灵活使用这个字段的话,可以按以下方法设置:

modes.py

class Book(models.Model):
title = models.CharField(verbose_name="书名", max_length=32)
second_title = models.CharField(verbose_name="副标题", max_length=32, blank=True, null=True)
author = models.CharField(verbose_name="作者", max_length=32)
translator = models.CharField(verbose_name="译者", max_length=32, blank=True, null=True)
intro = models.TextField(verbose_name="描述")
pic = models.FileField(verbose_name="封面图片", max_length=64, upload_to='book_cover', null=True, blank=True)
tags = models.ManyToManyField(Tags, verbose_name='书籍标签', blank=True)
prizes = models.ManyToManyField(Prizes, verbose_name='获奖详情', blank=True)
sump = models.IntegerField(verbose_name="收藏人数", default=0)
rate_num = models.IntegerField(verbose_name="评分人数", default=0)
num = models.IntegerField(verbose_name="浏览量", default=0)
published_time = models.DateField(blank=True, null=True, verbose_name='出版时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

class Meta:
db_table = 'book'
verbose_name = "图书"
verbose_name_plural = "图书"

def __str__(self):
return self.title

adminx.py

# 书籍管理
class BookAdmin(object):
search_fields = ['title', 'author', 'intro'] # 检索字段
list_display = ['id', 'show_pic', 'title', 'second_title', 'author', 'translator', 'published_time', 'intro',
'tags', 'prizes', 'num', 'sump', 'rate_num'] # 要显示的字段
list_filter = ['published_time', 'tags', 'prizes'] # 分组过滤的字段
ordering = ('id',) # 设置默认排序字段,负号表示降序排序
list_per_page = 30 # 默认每页显示多少条记录,默认是100条
model_icon = 'fa fa-book' # 左侧小图标
list_editable = ['title', 'author', 'intro', 'published_time'] # 可编辑字段
style_fields = {'tags': 'm2m_transfer', 'prizes': 'm2m_transfer'} # 控制字段的显示样式
filter_horizontal = ('tags', 'prizes') # 水平选择编辑多对多字段

重点是设置style_fields 和filter_horizontal ,效果:

python框架Django使用xadmin管理后台数据_Django_09

点我下载xadmin的demo

九、遇到的问题和解决方案
1、render() got an unexpected keyword argument ‘renderer’

使用Django2.0和xadmin2.0版本以上的可能会遇到这个问题。

解决方案:

在虚拟环境中找到Lib\site-packages\xadmin\views\dashboard.py

也可以点击两次shift键搜索dashboard.py,然后在dashboard.py修改以下内容

在大概36行处增加一个参数

def render(self, name, value, attrs=None, renderer=None):

如下图所示

python框架Django使用xadmin管理后台数据_Django_10

十、一些有用的设置
1、把静态文件集中到static中

先在项目根目录下创建一个static文件夹

然后在settings.py中设置

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

最后执行下面的命令:

python manage.py collectstatic
2、django app 如何在后台显示中文名

1.在app (这里以user为例)下面的__init__.py文件中

添加:

default_app_config = 'user.apps.UserConfig'

2.在apps.py中

from django.apps import AppConfig

class UserConfig(AppConfig):
name = 'user'
verbose_name = '用户'
3、xadmin通过展开方式显示TextField字段类型

由于TextField字段类型内容可能很长,在后台显示时很占屏幕位置,可以通过按钮来控制显示,代码如下:

models.py中定义了一个TextField字段类型:

class Prizes(models.Model):
name = models.CharField(max_length=32, verbose_name="奖项")
intro = models.TextField(blank=True, null=True, verbose_name='简介')

class Meta:
db_table = 'prizes'
verbose_name = "奖项"
verbose_name_plural = "奖项"

def __str__(self):
return self.name

在adminx.py中代码如下:

import xadmin
from django.utils.safestring import mark_safe
from xadmin import views

from .models import *

# 奖项管理
class PrizesAdmin(object):
search_fields = ['name'] # 检索字段
list_display = ['id', 'name', 'show_intro']
list_filter = ['name']
ordering = ('id',)

def show_intro(self, obj):
# 显示简介
if not obj.intro:
return mark_safe('')
if len(obj.intro) < 20:
return mark_safe(obj.intro)

short_id = f'{obj._meta.db_table}_short_text_{obj.id}'
short_text_len = len(obj.intro) // 4
short_text = obj.intro[:short_text_len] + '......'
detail_id = f'{obj._meta.db_table}_detail_text_{obj.id}'
detail_text = obj.intro

text = """<style type="text/css">
#%s,%s {padding:10px;border:1px solid green;}
</style>
<script type="text/javascript">

function openShutManager(oSourceObj,oTargetObj,shutAble,oOpenTip,oShutTip,oShortObj){
var sourceObj = typeof oSourceObj == "string" ? document.getElementById(oSourceObj) : oSourceObj;
var targetObj = typeof oTargetObj == "string" ? document.getElementById(oTargetObj) : oTargetObj;
var shortObj = typeof oShortObj == "string" ? document.getElementById(oShortObj) : oShortObj;
var openTip = oOpenTip || "";
var shutTip = oShutTip || "";
if(targetObj.style.display!="none"){
if(shutAble) return;
targetObj.style.display="none";
shortObj.style.display="block";
if(openTip && shutTip){
sourceObj.innerHTML = shutTip;
}
} else {
targetObj.style.display="block";
shortObj.style.display="none";
if(openTip && shutTip){
sourceObj.innerHTML = openTip;
}
}
}
</script>
<p id="%s">%s</p>
<p><a href='###' οnclick="openShutManager(this,'%s',false,'点击关闭','点击展开','%s')">点击展开</a></p>

<p id="%s" style="display:none">
%s
</p>
""" % (short_id, detail_id, short_id, short_text, detail_id, short_id, detail_id, detail_text)
return mark_safe(text)

show_intro.short_description = '描述'

注意:复制代码后需要做如下修改:

python框架Django使用xadmin管理后台数据_Django_11

一开始显示效果:

python框架Django使用xadmin管理后台数据_Django_12

点击展开效果:

python框架Django使用xadmin管理后台数据_Django_13

4、xadmin后台批量操作

adminx.py

import xadmin
from django.db.models import Sum
from xadmin.plugins.actions import BaseActionView

class MyCountFeeAction(BaseActionView):
"""
用户余额统计
"""
action_name = "countuserfee" #: 相当于这个 Action 的唯一标示, 尽量用比较针对性的名字
description = u'统计用户总余额' #: 描述, 出现在 Action 菜单中, 可以使用 ``%(verbose_name_plural)s`` 代替 Model 的名字.
model_perm = 'view' # 权限

def do_action(self, queryset):
all_balance = MallUser.objects.all().aggregate(Sum('balance'))
return HttpResponse(f'用户总余额{all_balance}')
class UserAdmin(object):
"""用户信息管理"""
list_display = ['username', 'balance', 'status', 'addtime']
search_fields = ['username', ]
list_filter = ['status', 'addtime']
list_per_page = 30 # 默认每页数量
model_icon = 'fa fa-user'
list_editable = ['status']
ordering = ['-addtime']
actions = [ MyCountFeeAction] # 添加批量选择操作

python框架Django使用xadmin管理后台数据_Django_14

5、xadmin过滤器外键显示特定值(比如只能过滤自己与超级管理员定义的数据)

首先,修改xadmin源码,修改xadmin/filters.py,在401行,做如下修改,

把self.lookup_choices = field.get_choices(include_blank=False)
改为:
# 调用自定义的方法
if hasattr(model_admin, '{field}_choices'.format(field=field.name)):
self.lookup_choices = getattr(model_admin, '{field}_choices'.format(field=field.name))(field, request,params, model,model_admin,field_path)
else:
self.lookup_choices = field.get_choices(include_blank=False)

如图:

python框架Django使用xadmin管理后台数据_Django_15

然后,在adminx.py中定义过滤的方法:

import xadmin
from django.db.models import Q, Sum
from xadmin.plugins.actions import BaseActionView

class MeasurePointAdmin(object):
# search_fields = ['user__name', 'user__account'] # 检索字段
list_display = ['num', 'elevation', 'correct_num', 'cumulative_amount']
list_filter = ['user', 'is_default', 'create_time'] # 分组过滤的字段
list_editable = ['num', 'elevation', 'correct_num', 'cumulative_amount']
ordering = ('id',) # 设置默认排序字段,负号表示降序排序
list_per_page = 30 # 默认每页显示多少条记录,默认是100条
model_icon = 'fa fa-users' # 左侧小图标
readonly_fields = ['user', 'is_default']
import_excel = True
actions = [MyCountFeeAction]

# 定义的函数名必须是 字段名_choices
def user_choices(self, field, request, params, model, model_admin, field_path):
# 超级用户不做控制
if self.request.user.is_superuser:
return field.get_choices(include_blank=False)

# 过滤器只显示自己与超级管理员
user_lst = field.related_model._default_manager.filter(Q(id=self.request.user.id) | Q(is_superuser=True))
# 返回格式 [('pk','标题'),]
return [(user.id, user.username) for user in user_lst]

效果:

python框架Django使用xadmin管理后台数据_Django_16

python框架Django使用xadmin管理后台数据_Django_17