美文网首页
xadmin进阶应用,并替换Django的admin

xadmin进阶应用,并替换Django的admin

作者: Jayden_wu | 来源:发表于2019-07-10 21:35 被阅读0次

    软件版本

    python 3.7.2
    Django 2.1.5
    xadmin 2.0.1
    PyCharm

    首先给大家看下效果图

    image

    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
        # 类似<a 的href
        list_display_links = ['id']
    
    class BaseSetting(object):
        # 启用主题
        enable_themes = True
        use_bootswatch = True
    
    # 所有配置,model等统一注册
    xadmin.site.register(views.CommAdminView, GlobalSetting)
    xadmin.site.register(models.User, UserAdmin)
    xadmin.site.register(views.BaseAdminView, BaseSetting)
    
    

    这里还需要补充一点,在菜单栏右侧还需要把菜单组中文化,如下操作

    # 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 中对象是不可以直接序列化的,只有其自身对象才可以
    image

    下面给大家看个例子,实现上面需求的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

    image

    到这里基本就结束了。

    作者:小成吉思汗的创作世界
    链接:https://www.jianshu.com/p/4107672cbd57

    相关文章

      网友评论

          本文标题:xadmin进阶应用,并替换Django的admin

          本文链接:https://www.haomeiwen.com/subject/ecgkkctx.html