python框架Django使用xadmin管理后台数据
Django使用xadmin管理后台数据
关注公众号“轻松学编程”了解更多。
作用:xadmin比Django内置的admin更美观、更方便。
一、导入xadmin(第三方库)
方法1、使用pip安装
pip install git+git://github.com/sshwsfc/xadmin.git
如果出现问题可参考https://blog.csdn.net/lm_is_dc/article/details/80558073解决
方法2、可直接到gitHub上找到xadmin的地址https://github.com/sshwsfc/xadmin 下载到项目根目录 ,然后pip:
pip3 install xadmin-master.zip
安装。
注意:如果使用的Django2.0版本以上的,需要到GitHua上找到xadmin,然后拉取django2的分支。
如果出现缺少安装包的可参考:
https://blog.csdn.net/Snail0Li/article/details/79694781
二、在settings.py里面配置
在注册应用处加上
'xadmin',
'crispy_forms',
三、在路由urls.py里面添加路由
import xadmin
urlpatterns = [
url('xadmin/', xadmin.site.urls),
]
四、数据迁移
makemigrations
migrate
五、建立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)
六、创建管理员
createsuperuser
七、效果图
八、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 ,效果:
九、遇到的问题和解决方案
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):
如下图所示
十、一些有用的设置
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 = '描述'
注意:复制代码后需要做如下修改:
一开始显示效果:
点击展开效果:
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] # 添加批量选择操作
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)
如图:
然后,在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]
效果:
后记
【后记】为了让大家能够轻松学编程,我创建了一个公众号【轻松学编程】,里面有让你快速学会编程的文章,当然也有一些干货提高你的编程水平,也有一些编程项目适合做一些课程设计等课题。
也可加我微信【1257309054】,拉你进群,大家一起交流学习。
如果文章对您有帮助,请我喝杯咖啡吧!
公众号