DjangoAdmin

DjangoAdmin本身就是一套大而全的系统,官方文档中介绍了很多配置方法,但仍然有大量的骚操作是文档中没有的,所以遇到特殊需求的时候,求助文档不一定有用。

在我看来 DjangoAdmin 虽然能快速生成一套管理后台,但如果要做大量特殊需求的定制,其成本不亚于用 Vue/React 重新开发一套,简单的使用成本不高,但深入定制的话需要对 DjangoAdmin 的工作流程比较熟悉,把源码啃熟了(有些 Python 源码没有类型注解是很难读懂的),才能在原有基础上雕花,有时候还存在着后续维护的问题。

不过还是瑕不掩瑜了,谁能拒绝配置了几行代码就可以用的管理后台呢?

而且还不需要你做出一套 RESTFul API 来实现前后端分离,直接一把梭,起飞~

一些参考资料

界面主题

GitHub 上有很多 DjangoAdmin 的替换主题,所以不要抱怨 DjangoAdmin 的界面丑啦,好看的主题很多!

我最先使用的是 adminx,但这个侵入性太强了,需要对 admin 的配置代码做大量修改,实在是不划算,可能官方也意识到这个问题,后续应该是停更了。

到了 Django 2.x 时代后面,admin 的界面主题多了起来,有个国产的 SimpleUI 很不错,基于 Vue + ElementUI 实现的,star很多,算是比较成熟的一类,我愿称之为国产之光。

其他的我也大多有测试,但用起来总有一些兼容的问题,所以目前还是比较推荐国产之光。

SimpleUI

已经在多个产品中使用,使用 vue+elementUI(非单页应用),支持多标签页

一些相关的参考资料

django-jazzmin

地址:https://github.com/farridav/django-jazzmin

这个是偶然发现的,对于看腻了 ElementUI 的人来说,会有眼前一亮的感觉

使用 Bootstrap+AdminLTE 重写,效果还不错

(就是偶尔会莫名卡死

而且细节方面做得不如 SimpleUI,比如搜索框没有 placeholder 的提示之类的。

定制案例

本文只记录特殊需求的实现,对于 DjangoAdmin 的常规配置就不复制粘贴了,网上随便一搜都有很多。

我之前已经写过不少 DjangoAdmin 的定制案例文章了,最近也做了不少定制,不过我不想写新文章来单独记录某个需求的实现过程了,直接在本文里记录,同时保持本文更新~

添加自定义列

本案例基于 SimpleUI

效果图

实现过程

这里使用的是 ElementUI 的 Tag 组件,文档:https://element.eleme.cn/#/zh-CN/component/tag

前面提到过 SimpleUI 不是单页应用,是直接在网页上使用 vue 和 elementUI,并没有webpack环境

所以要加入 elementUI 的组件不能直接简单的

<el-tag type="success">标签</el-tag>

而是要用 webpack 生成出来的

<div class="el-tag el-tag--success el-tag--light">标签</div>

ok,开始上Python代码

假设有个 model 叫 Invoice,中文名发票,定义如下

class Invoice(models.Model):
invoice_type = models.CharField('发票类型')

在需要自定义的 ModelAdmin 中,增加一个方法

# 发票类型颜色
@admin.display(description='发票类别')
def invoice_type_tag(self, obj: Invoice):
def el_tag(color_type, content):
"""
生成 ElementUI 的 tag 组件
:param color_type: success, info, warning, danger
:param content:
:return:
"""
from django.utils.safestring import mark_safe
type_class = '' if len(color_type) == 0 else f'el-tag--{color_type}'
return mark_safe(f'<div class="el-tag el-tag--small {type_class} el-tag--light">{content}</div>') if obj.invoice_type.startswith('普通'):
return el_tag('', obj.invoice_type)
if obj.invoice_type.startswith('专用'):
return el_tag('danger', obj.invoice_type)
if obj.invoice_type.startswith('电子专票'):
return el_tag('info', obj.invoice_type)
if obj.invoice_type.startswith('电子普票'):
return el_tag('warning', obj.invoice_type)

然后把这个 invoice_type_tag 加到 list_display 中即可

PS:这里的 @admin.display() 装饰器是Django3.2版本之后新增的,很方便,相当于以前的

invoice_type_tag.short_description = '发票类别'

PS:注意HTML代码需要用 mark_safe 方法包装起来,才能正常渲染,不然会被转义!

显示进度条

效果图

实现过程

原理同上面的添加自定义列

代码如下

# 进度条
@admin.display(description='进度条')
def progress_bar(self, obj):
html = f'''
<div role="progressbar" aria-valuenow="{obj.progress}" aria-valuemin="0" aria-valuemax="100"
class="el-progress el-progress--line is-light el-progress--text-inside">
<div class="el-progress-bar">
<div class="el-progress-bar__outer" style="height: 22px;">
<div class="el-progress-bar__inner" style="width: {obj.progress}%;">
<div class="el-progress-bar__innerText">{obj.progress}%</div>
</div>
</div>
</div>
</div>
'''
from django.utils.safestring import mark_safe
return mark_safe(html)

页面上显示合计数额

效果图

实现过程

这个功能比较麻烦,因为需要魔改 template

首先我们要知道,这个列表对应的是哪个 template,在 admin 包的 templates 目录下面的找了半天,最终发现这个页面是 change_list ,而且因为页面比较复杂,被分成了好几部分

我们只需要修改 change_list.html 这个文件就行了。

admin.py

OK,模板代码先不管,我们来写Python代码计算总金额。

要实现将数据放在 context 里传给 template,得重写个 ChangeList 对象

from django.db.models import Sum
from django.contrib.admin.views.main import ChangeList class InvoiceChangeList(ChangeList):
def get_results(self, request):
super(InvoiceChangeList, self).get_results(request)
totals = self.result_list.aggregate(Sum('amount'))
self.total_amount = totals['amount__sum']

使用 Sum 这个聚合方法,计算总金额。

通过Python语言的动态特性,加 total_amount 这个属性添加到 ChangeList 对象中

这样在 template 里就能通过 {{ cl.total_amount }} 的方式拿到这个属性。

然后改一下 ModelAdmin :

class InvoiceAdmin(ImportExportModelAdmin):
# 如果你改了 template 的名称,这里可以对应修改,否则默认即可
change_list_template = 'change_list.html' # 添加这个代码
def get_changelist(self, request, **kwargs):
return InvoiceChangeList

后端部分搞定了,接下来是前端的模板部分。

template

为了在页面上添加新元素,我们来修改 change_list.html 文件。

注意,不要直接复制这个文件来修改!原因是你修改完的 template 会覆盖其他组件,这样以后换 admin 主题,或者使用 import-export 这类会修改 admin 页面的插件时无法生效,也就是所谓的兼容问题。

Django也想到了这种情况,这些 template 都是组件化的,我们写一个扩展 template 就可以了。

在项目的 templates/admin 目录下新建 change_list.html 文件,代码如下

{% extends "admin/import_export/change_list.html" %}

{% block result_list %}
{{ block.super }}
<div style="text-align: right; margin: 20px 5px; font-size: 20px;">
总金额:{{ cl.total_amount }} 元
</div>
{% endblock %}

注意:如果用了 django-import-export 插件,则要根据使用到的功能来添加 object-tools-items block。

比如你的 ModelAdmin 继承自 ImportExportModelAdmin,那我们转到源码,可以看到它重写了 template

class ImportExportMixin(ImportMixin, ExportMixin):
"""
Import and export mixin.
"""
#: template for change_list view
change_list_template = 'admin/import_export/change_list_import_export.html' class ImportExportModelAdmin(ImportExportMixin, admin.ModelAdmin):
"""
Subclass of ModelAdmin with import/export functionality.
"""

然后再看看 admin/import_export/change_list_import_export.html 这个文件

{% extends "admin/import_export/change_list.html" %}

{% block object-tools-items %}
{% include "admin/import_export/change_list_import_item.html" %}
{% include "admin/import_export/change_list_export_item.html" %}
{{ block.super }}
{% endblock %}

可以看到它在 object-tools-items 中添加了俩组件,把这一块 block 的代码复制到我们的 change_list.html 中即可。

参考资料

扩展工具

这部分记录我在逛GitHub时发现的比较有意思的扩展库,记录一下

Django AdminPlus

地址:https://github.com/jsocol/django-adminplus

可以方便的给admin增加新页面

django-adminactions

地址:https://github.com/saxix/django-adminactions

可以给admin添加一系列的actions

  • Export as CSV
  • Export as Excel
  • Export as fixture
  • Export delete tree
  • Mass update records
  • Graph queryset
  • Merge records
  • Find Duplicates

中秋快乐!新鲜出炉一篇DjangoAdmin使用合集,DjangoAdmin的功能比你想象的强大!的更多相关文章

  1. 23套新鲜出炉的网站和手机界面 PSD 素材

    Web 用户界面,移动用户界面和线框套件对设计师很有用,因为这些套件让他们使用快速和有效的方式复制用户界面.这些类型的工具包提供了一个基本的用户界面元素,用于它们需要制作的网站或软件模型. 在这篇文章 ...

  2. 22套新鲜出炉的 Web & Mobile PSD 用户界面素材

    在这篇文章中,我们展示的是自由和清新的 UI 设计素材套件.这些线框图和 UI 设计工具包让设计师在设计用户界面原型的时候能够非常便利. Web 用户界面,移动用户界面和线框套件对设计师很有用,因为这 ...

  3. 新鲜出炉的30个精美的 jQuery & CSS3 效果【附演示和教程】

    新鲜出炉的30个精美的 jQuery & CSS3 效果[附演示和教程]   作为最流行的 JavaScript 开发框架,jQuery 在现在的 Web 开发项目中扮演着重要角色,它简化了 ...

  4. 15个新鲜出炉的 Photoshop 文本效果教程

    文本效果可能是 Photoshop 图形设计中最常用和最通用的技术之一.最重要的是你可以使用任何效果,风格或纹理来产生有趣的排版,越多人尝试过它并制作了一些精彩的教程.所以这篇文章旨在为您提供全面的 ...

  5. 微信小程序开发视频教程新鲜出炉

    微信小程序开发公测了,可是对于新手来说,不同的框架不同的开发机制,如何快速适应呢?微信小程序开发视频教程新鲜出炉了,从零开始一步一步搭建微信小程序,每个章节都会涉及到不同的知识点,等教程学习完你不但掌 ...

  6. 刚写完的商城erp + 这个商城前台,新鲜出炉。自己1个人写, 包括php框架和前端html页面.

    刚写完的商城erp + 这个商城前台,新鲜出炉.自己1个人写, 包括php框架和前端html页面. 刚写完的商城erp + 这个商城前台,新鲜出炉.自己1个人写, 包括php框架和前端html页面.

  7. 20个新鲜出炉的网站模板【HTML & PSD】

    这里给大家分享20 个新鲜出炉的免费网站模板.这些设计元素将成为你下一个项目的重要素材,可以帮你节省很多的时间.与往常一样,我们经常漫游网络,寻找最好的资源, HTML.CSS 和 PSD 等等,记得 ...

  8. 分享25个新鲜出炉的 Photoshop 高级教程

    网络上众多优秀的 Photoshop 实例教程是提高 Photoshop 技能的最佳学习途径.今天,我向大家分享25个新鲜出炉的 Photoshop 高级教程,提高你的设计技巧,制作时尚的图片效果.这 ...

  9. PS教程:20个新鲜出炉的 Photoshop 中级教程

    Photoshop 实例教程是提高 Photoshop 技能的最佳学习途径.今天,我向大家分享最新20个 Photoshop 进阶教程,提高你的图片处理技巧,制作时尚的效果.这些教程可以帮助把你的想法 ...

随机推荐

  1. SpringBoot配置多环境下的properties配置文件

    1.新建SpringBoot项目之后,再另外创建两个properties文件 2.配置详情 主文件 dev和test文件 两者只是里面的配置信息有所不同而已,比如mysql, redis, nacos ...

  2. MAC帧的格式&&wireshark分析MAC帧

    MAC帧的格式 MAC帧较为简单,由五个字段组成 目的地址:6字节 源地址:6字节 类型字段:2字节,用来标志上一层使用的是什么协议,以便把收到的MAC地址帧的数据交给上一层的这个协议. 数据字段:其 ...

  3. Random生成指定范围的随机数和对象数组

    查看类 ~java.util.Random :该类需要 import导入使后使用. 查看构造方法 ~public Random() :创建一个新的随机数生成器. 查看成员方法 ~public int ...

  4. gerrit系统如何配置访问控制

    . 版本:v0.3 作者:河东西望 日期:2022-7-13 . 目录 1 关键概念 2 需求场景 3 配置策略 gerrit系统的上手使用有两个难点: 部署repo仓库. 配置访问控制. 想要上手使 ...

  5. Proxmox6.2简单配置

    刻录: 使用rufus+GPT+DD方式写入U盘 一.更换国内源: 1)删除企业源 mv /etc/apt/sources.list.d/pve-enterprise.list /etc/apt/so ...

  6. 零基础学Java(9)在mac上运行命令行提示"找不到或无法加载主类"

    天坑 遇到的问题:使用命令行执行命令:java EightSample,会报以下错误 错误: 找不到或无法加载主类 EightSample 运行环境 mac系统 IntelliJ IDEA编译器 Ja ...

  7. Unity3D学习笔记9——加载纹理

    目录 1. 概述 2. 详论 2.1. Resources方式 2.2. API方式 2.3. Web方式 1. 概述 理论上,Unity中加载纹理并没有什么难度,只需要将图片放置在Assets文件夹 ...

  8. 获取某个html元素相对于视窗的位置集合

    getBoundingClientRect() getBoundingClientRect()获取元素位置,这个方法没有参数 getBoundingClientRect()用于获得页面中某个元素的左, ...

  9. css基础02

    熟练快捷键!方便,要多练!  css复合选择器 不会选孙子,有一个儿子和另一个儿子的孩子(也是孙子)同名了,但子选择器子选择儿子,同名的孙子不选.和后代选择器有一点不一样的. " ,&quo ...

  10. 技术分享 | innodb_buffer_pool_size为什么无法调低至1GB以内

    前言 innodb_buffer_pool_size可以调大,却不能调小至1GB以内,这是为什么? MySQL 版本:5.7.30 测试环境有台 MySQL 服务器反应很慢,检查系统后发现内存使用量已 ...