最近在做一个项目,后台计划用Python实现,采用django+xadmin的组合。网上关于xadmin的教程很零散,官方文档的网址还打不开,略有尴尬,此篇文章是xadmin使用的一些心得。如果需要源码请留言。
软件版本
python 3.7.2
Django 2.1.5
xadmin 2.0.1
PyCharm
首先给大家看下效果图
xadmin的安装
常用的安装方式有两种,一种是源码安装,一种是通过pip安装
源码安装方式
从https://github.com/sshwsfc/xadmin 下载xadmin zip文件,然后解压。
在项目app下,比如user下新建文件夹extra_app,将解压后的文件夹xadmin拷贝到extra_app中,然后在文件夹extra_app上点击右键选择'Mark Directory as Sources Root'。
pip 安装方式
pip install git+git://github.com/sshwsfc/xadmin.git@django2
然后在项目的settings.py中添加如下配置
INSTALLED_APPS = [
.....
'xadmin',
'crispy_forms',
'reversion'
]
假如你是用的MySql数据库,进行如下配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydb',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '139.107.172.158',
'PORT': '3306',
}
}
同时可以把语言改成中文,时区改成上海
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False # 如果没有国际化的需求写False,否则数据中插入时间时,有警告。
下一步配置路由,打开项目的urls.py做如下修改
urlpatterns = [
......
path('admin/', xadmin.site.urls),
]
到这一步其实就可以跑起来了
···
python mange.py runserver
···
然后访问http://127.0.0.1:8000/admin/,应该就是登录界面了,这里就不截图了。
个性化定制我们的后台管理系统 和 自定义显示列-第一种情况
下面以user 模块为例
models.py代码如下,直接看注释吧
from django.db import models
import datetime
# 外勤
class User(models.Model):
name = models.CharField(verbose_name='姓名', max_length=200)
pwd = models.CharField(verbose_name='密码', max_length=100)
job_number = models.IntegerField(verbose_name='工号')
phone = models.CharField(verbose_name='电话号码', max_length=100, null=True, blank=True)
class Meta:
# 设置model在后台管理系统中的中文名称
verbose_name = '外勤信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
# 自定义显示列,在后台中显示列名为“总诊断量”
def get_report_all_nums(self):
return self.report_set.all().count()
get_report_all_nums.short_description = '总诊断量'
# 自定义显示列,在后台中显示列名为“月度断量”
def get_report_month_nums(self):
year = datetime.datetime.now().year
month = datetime.datetime.now().month
first_day = datetime.datetime(year, month, 1)
today = datetime.datetime.now()
return self.report_set.filter(report_date__lt=today, report_date__gt=first_day).count()
get_report_month_nums.short_description = '月度诊断量'
修改user 模块中admin.py如下
import xadmin
from xadmin import views
from msuser import models
class GlobalSetting(object):
# 后台管理系统的名字
site_title = '系统后台'
# 管理系统的设计者,当然你可以改成其他内容
site_footer = 'Design by XHY'
# 左侧菜单栏是否可隐藏
# menu_style = 'accordion'
class UserAdmin(object):
# 用户管理的图标, 默认是圆圈,丑
model_icon = 'fa fa-home'
# 显示的列,对应model相应字段名
list_display = ['id', 'name', 'pwd', 'job_number', 'phone', 'get_report_month_nums', 'get_report_all_nums']
# 过滤器,用于查找,这是xadmin的强大之处
list_filter = ['job_number', 'name', 'phone']
# 搜索字段
search_fields = ['job_number', 'name', 'phone']
# 每页显示的数据行数
list_per_page = 20
# 类似
这里还需要补充一点,在菜单栏右侧还需要把菜单组中文化,如下操作
# user 模块下的apps.py
from django.apps import AppConfig
class UserConfig(AppConfig):
name = 'msuser'
verbose_name = '用户管理'
# user 模块下的__init__.py
default_app_config = 'msuser.apps.MsuserConfig'
自定义显示列-第二种情况
在实际应用中,我们经常处理一对多的问题,也就是外键。有的时候项目的需求很诡异,举个例子,不仅要用用户的ID作为报告表的外键,同时在报告这个表中还要显示用户的工号,你说这气不气人。如果整个后台时自己写还好解决,但咱们时用的xadmin,经过研究发现,如下方法实现
models.py
from django.db import models
from msuser.models import User
# 报告
class Report(models.Model):
# 外键
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='外勤姓名')
report_date = models.DateTimeField(verbose_name='诊断时间')
......
class Meta:
# 设置model在后台管理系统中的中文名称
verbose_name = '诊断报告'
verbose_name_plural = verbose_name
# 一会在生成json字符串时使用
def convert_to_dict(self):
my_dict = {}
my_dict.update(self.__dict__)
my_dict.pop("_state")
my_dict.pop("report_date")
return my_dict
相应模块的admin.py
import xadmin
from msdiagnosis import models
class ReportAdmin(object):
model_icon = 'fa fa-home'
list_display = ['id', 'user', 'get_job_number', 'report_date']
list_filter = ['report_date', 'user']
# 这里需要注意的是, 在报告页面,不仅可以根据外键查询,
# 还可以根据用户的其他列查询,比如姓名,工号
# 注意书写方式,双下划线 user__name
search_fields = ['user__id', 'user__name', 'user__job_number']
list_per_page = 20
list_display_links = ['id']
# 自定义显示列, 是用户的工号,在reprot数据库的表中,其实是没有这一列的
def get_job_number(self, obj):
return '%s' % obj.user.job_number
get_job_number.short_description = '外勤工号'
xadmin.site.register(models.Report, ReportAdmin)
python 下的json字符串生成
这里不得不吐槽一下,相比List或对象转json字符串,python的转换过程真的和粑粑一样恶心,最后优化优化在优化,也没有java导几个库,然后直接仍list或对象简单。
我们的需求是这样的,当app请求服务端时,返回如下格式的json。
{
"code": 0,
"msg": "成功",
"data": [
{
"id": 2,
"name": "Cysion",
"age": 29,
"pid": "3708261989",
"gender": 0
},
{
"id": 11,
"name": "Sophia",
"age": 22,
"pid": "3708261998",
"gender": 1
},
{
"id": 15,
"name": "lisi",
"age": 13,
"pid": "3708262005",
"gender": 0
}
]
}
python 中对象是不可以直接序列化的,只有其自身对象才可以
下面给大家看个例子,实现上面需求的json
from django.http import JsonResponse, HttpResponse
from .models import Report
# app 获取诊断列表
def get_diagnosis_list(request):
report_list = Report.objects.filter(user=2)
# 需求的json格式 {"code": 1, "msg": "获取诊断列表成功", "data": ""}
# 下面的5行就是在为生成json做准备,其实是dict格式, 到return才是生成了真正的json
res = {"code": 1, "msg": "获取诊断列表成功"}
r_list = []
for r in report_list:
r_list.append(r.convert_to_dict())
res["data"] = r_list
return JsonResponse(res, safe=False)
最后生成的json
到这里基本就结束了。