详解Django admin高级用法


Posted in Python onNovember 06, 2019

使用Django意味着后台框架的几乎所有内容都会和Django产生互动,排除功能全部手撸的情况.

Django 后台admin有大量的属性和方法,拥有强大的功能和自定义能力.通过完整的代码来看Django admin的基础设置和高级用法,并结合form表单来实现深度自定义.

简单使用

如果只是使用admin自带的数据管理功能,只需要将模型注册到admin中,就可以实现.

from django.contrib import admin
admin.site.register(News)
admin.site.register(NewsType)
admin.site.site_header = "数据库"
admin.site.index_title = "新闻后台"

Django后台会将对应数据表的所有字段进行展示,默认点击 id 会进入修改页面,对应 change_form.html 模板.

自定义admin类

使用admin也可以自定义一个admin的类,来自定义后台实现的属性和方法,然后通过 register() 来将自定义的类和模型注册在一起.

注册方式有两种,一种是使用类装饰器,一种是使用 site

from django.contrib import admin
# 装饰器注册
@admin.register(ModelClass)
class CustomAdmin(admin.ModelAdmin):
  list_display = '__all__'
# 使用site
class CustomAdmin(admin.ModelAdmin):
  exclude = ['id']
admin.site.register(CustomAdmin, ModelClass)

admin显示属性的设置

ModelAdmin中的属性设置

admin可以设置在列表页和详情页显示的字段以及搜索字段等的限制,在admin的类中可以直接定义.

以使用较多的 ModelAdmin 为例, ModelAdmin 源码中的属性有:

# 在列表页显示的字段,默认会显示所有字段,有对应的方法可以重写
list_display = ('__str__',)
# 在列表页显示的字段中,可以链接到change_form页面的字段
list_display_links = ()
# 右侧的筛选,必须是字段,可以继承自SimpleListFilter来自定义筛选字段和规则,SimpleListFilter的方法在后面详细介绍
list_filter = ()
# 联表查询是否自动查询,可以是布尔,列表或元组,如果是列表或元组,则级联查询指定的字段
list_select_related = False
# 列表页每页展示的条数
list_per_page = 100
# 分页,显示全部,真是数据小于该值时才会显示全部
list_max_show_all = 200
# 在列表页可以编辑的字段
list_editable = ()
# 在列表页可以模糊搜索的字段
search_fields = ()
# 对Date和DateTime类型进行搜索
date_hierarchy = None
# 在change_form页面,按钮为,save按钮的值(save as new和save add another)
save_as = False
# 点击保存并继续编辑
save_as_continue = True
# save按钮的位置,是True则显示在页面上方
save_on_top = False
# 自定义分页类
paginator = Paginator
# 详细页面,删除、修改,更新后跳转回列表后,是否保留原搜索条件管理员现在在创建,编辑或删除对象后保留列表视图中的过滤器。
# 可以将此属性设置为False,以恢复之前清除过滤器的行为。
preserve_filters = True
# 在详情页面,如果有FK到其他表,在详情页中可以动态的填加或删除级联数据
inlines = []
admin中action操作的设置
admin中的action是指在列表页的动作,默认为删除所选的条目,可以自定义填加动作,将动作注册到action中,需要是一个方法
# 定制action中的操作
actions = []
action_form = helpers.ActionForm
# action选项显示的位置,页面上方或者页面下方
actions_on_top = True
actions_on_bottom = False
# 是否显示action选择的个数
actions_selection_counter = True
checks_class = ModelAdminChecks
BaseModelAdmin中的属性
除了ModelAdmin中的属性,也可以自定义在其父类BaseModelAdmin中的属性和方法,是一些通用的,在继承子BaseModelAdmin的类中也可以完成的属性设置.一般是详情页的属性.
# 自动补全,外键查询数据多时,方便查找
autocomplete_fields = ()
# 详情页,针对外键和M2M字段变成input框形式
raw_id_fields = ()
# 详情页面展示的字段
fields = None
# 详情页面排除的字段,字段可以是数据库中的也可以是自定义的
exclude = None
# 在详情页面对数据进行分隔显示,对应到admin模板中的'fieldsets.html'
fieldsets = None
# 为详情页指定form表单,可以自定义显示的数据,字段
form = forms.ModelForm
# 下面两个是M2M显示时,数据移动选择.可以参考admin中用户的权限操作
filter_vertical = () # 纵向展示
filter_horizontal = () # 横向展示
# 详情页面使用radio显示选项,FK默认使用select
radio_fields = {}
# 填加页面,在某字段输入值后,自动填加到指定字段
# prepopulated_fields = {"email": ("user",)},email字段会在用户填加user字段时自动填充
prepopulated_fields = {}
# 详情页指定显示的插件,后面详细说明
formfield_overrides = {}
# 详情页面的只读字段
readonly_fields = ()
# 详情页面排序规则
ordering = None
# 禁止某些排序,为空则禁止所有的排序
sortable_by = None
# 编辑时是否在页面上显示view on set,可以通过方法来返回一个链接,后面说明
view_on_site = True
# 列表页,模糊搜索后面显示的数据个数样式
# 为True是显示条数,为False时显示全部
show_full_result_count = True
checks_class = BaseModelAdminChecks

模板的定制

指定自定义模板

在ModelAdmin中自带了几个指定模板的属性,可以自己定义HTML文件,来指定给某个模板页面

# Custom templates (designed to be over-ridden in subclasses)
# 添加数据模板页
add_form_template = None
# 修改数据的模板页
change_form_template = None
# 修改多条数据的模板页
change_list_template = None
# 删除确认信息模板页
delete_confirmation_template = None
# 删除关联数据的确认页
delete_selected_confirmation_template = None
# 修改历史的模板页
object_history_template = None
# 弹出框模板页
popup_response_template = None

重写自带模板

在django admin里面有自己写好的模板,include模板,每个app也有对应的模板

admin的自带模板在项目的 django/contrib/admin/templates/admin ,目录下面

include 文目录下是 include 语法包含的模板。

change_form.html 是数据修改页面的模板,如果想在数据详情页面自定义显示的内容,可以自定义这个页面

模板使用的全都是模板语法,注意模板语法的继承机制,在当前页面重写的元素,不会直接显示。

fieldset.htlm 是拼接成详情页的块。前面提到,自定义admin类中的 fieldset 属性,可以自定义详情页,使数据字段分块显示,就是改变了传给这个页面的值。

例如,使用 if 语句来动态添加jQuery和 div 标签,只有在访问某个app的数据时添加

{% if app_name in request.path %}
  <script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"></script>
<div>
<fieldset class="custom">

<div id="div"></div>
</fieldset>
{% endif %}

结合form表单

django admin结合form表单,重写 fieldset.html 来实现数据详情页面的深度自定义,通过处理form表单提交的数据,来实现后台功能的完全自定义。

django的admin中可以指定form类,来自定义显示的内容

from django import forms
# TagValueManager是自定义的类
from tag_manager import TagValueManager

class CustomAddForm(forms.ModelForm):

  """ 根据标签的id,动态生成下拉选项框 """
  for i in TagValueManager.all_tag:
    locals()[
      'field_tag_id_{}'.format(
        i['id'])] = forms.ChoiceField(
      choices=TagValueManager.get_choice(
        i['id']),
      label=i['name'])

  class Meta:
    model = CandidateTag
    fields = '__all__'
    exclude = ['tag_id', 'tag_value', 'ext_1', 'ext_2', 'candidate_id']

注意:在form表单中动态生成的属性,必须使用 fields='__all__‘ 属性,否则不会显示,可以结合 exclude 属性来控制需要显示的表单

然后在admin中注册form类

class CandidateTagAdmin(admin.ModelAdmin):
  list_display = [
    'id',
    'tag_count',
  ]
  form = CustomAddForm

自定义列表页来源

除了可以通过修改admin的属性,来实现列表页展示字段的自定义,也可以对列表页数据进行筛选,例如,筛选出活跃的用户等,这个可以在 action 中定义新的方法

也可以重写admin中的 get_queryset 方法,返回的qs是重新筛选之后的数据,可以避免一些业务逻辑上的误操作

这里的代码展示了,在列表页,展示其他表中的数据,注册模型表的数据没有展示

def get_queryset(self, request):
    """
    从candidate表中查询数据,在list_display中统计其标签个数
    """
    qs = Candidate.objects.all().order_by('id')
    return qs
## 处理form数据

给admin类定义form属性之后,在详情页面传回的数据,会带上form表单里面的数据,然后结合业务逻辑处理这个数据

例如,业务场景,接受form数据,保存到其他几张表,对于展示数据的表,不进行任何操作,那就需要重写 save_model 方法,这个方法调用了模型的 save 方法

重写这个方法:

def save_model(self, request, obj, form, change):
    """
    重写save_model方法
    """
    candidate_id = request.path.split('/')[4]
    post_dict = request.POST
    # 根据返回的form表单的标签来确定修改的tag_id
    include_field = 'field_tag_id_'
    for key, value in post_dict.items():
      if include_field in key:
        tag_id = key.split('_')[-1]
        tag_value = value
        try:
          obj, created = CandidateTag.objects.update_or_create(
            defaults={'tag_value': tag_value}, candidate_id=candidate_id, tag_id=tag_id)
        except Exception as e:
          tag_name = TagValueManager.all_tag.get(id=tag_id)['name']
          messages.add_message(request, messages.ERROR, '求职者的"{}"标签信息保存失败'.format(tag_name))

扩展

在 get_queryset 方法中,展示类模型中的统计数据,这个统计数据,不是在数据库中生成的,实在模型类中定义的方法,这个方法的返回值,可以在列表页中直接展示。例如上文中说道的标签的个数

同时,也可以返回一个HTML标签,模板语法中获取这个字段时,得到的是一个HTML标签,直接渲染

from django.utils.safestring import mark_safe
# 使用mark_safe
@mark_safe
def get_user_dept(self,obj):
  """ 这个方法在模型中 """
  return "<p>this is a HTML tag</p>"
# 允许HTML标签
get_report_depts.allow_tags = True
# HTML展示时的字段名
get_report_depts.short_description = '所属部门'

总结

以上所述是小编给大家介绍的Django admin高级用法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python深入学习之内存管理
Aug 31 Python
Python导入txt数据到mysql的方法
Apr 08 Python
在Python中使用base64模块处理字符编码的教程
Apr 28 Python
python3使用PyMysql连接mysql数据库实例
Feb 07 Python
Python中is与==判断的区别
Mar 28 Python
pandas对指定列进行填充的方法
Apr 11 Python
Python面向对象程序设计多继承和多态用法示例
Apr 08 Python
python二进制读写及特殊码同步实现详解
Oct 11 Python
python脚本调用iftop 统计业务应用流量的思路详解
Oct 11 Python
python pygame实现滚动横版射击游戏城市之战
Nov 25 Python
Django实现从数据库中获取到的数据转换为dict
Mar 27 Python
使用python实现名片管理系统
Jun 18 Python
Python全局锁中如何合理运用多线程(多进程)
Nov 06 #Python
Python实现socket非阻塞通讯功能示例
Nov 06 #Python
Python中生成一个指定长度的随机字符串实现示例
Nov 06 #Python
详解Python list和numpy array的存储和读取方法
Nov 06 #Python
python函数装饰器之带参数的函数和带参数的装饰器用法示例
Nov 06 #Python
Python list与NumPy array 区分详解
Nov 06 #Python
Django实现WebSSH操作物理机或虚拟机的方法
Nov 06 #Python
You might like
探讨PHP中OO之静态关键字以及类常量的详解
2013/06/07 PHP
thinkphp模板输出技巧汇总
2014/11/24 PHP
thinkphp 中的volist标签在ajax操作中的特殊性(推荐)
2018/01/15 PHP
JTrackBar水平拖动效果
2007/07/15 Javascript
菜鸟学习JavaScript小实验之函数引用
2010/11/17 Javascript
Kibo 用于处理键盘事件的Javascript工具库
2011/10/28 Javascript
浅析js中的浮点型运算问题
2014/01/06 Javascript
js 获取、清空input type=&quot;file&quot;的值示例代码
2014/02/19 Javascript
用原生JS获取CLASS对象(很简单实用)
2014/10/15 Javascript
js实现Select列表内容自动滚动效果代码
2015/08/20 Javascript
jQuery+ajax实现文章点赞功能的方法
2015/12/31 Javascript
js正则表达式replace替换变量方法
2016/05/21 Javascript
Angular之指令Directive用法详解
2017/03/01 Javascript
vue使用axios跨域请求数据问题详解
2017/10/18 Javascript
微信{"errcode":48001,"errmsg":"api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]"}
2018/10/12 Javascript
jQuery选择器之基本选择器用法实例分析
2019/02/19 jQuery
详解js根据百度地图提供经纬度计算两点距离
2019/05/13 Javascript
vue-cli和v-charts实现可视化图表过程解析
2019/10/08 Javascript
vue移动端使用appClound拉起支付宝支付的实现方法
2019/11/21 Javascript
python使用cPickle模块序列化实例
2014/09/25 Python
python监控网站运行异常并发送邮件的方法
2015/03/13 Python
python轻松实现代码编码格式转换
2015/03/26 Python
对python numpy数组中冒号的使用方法详解
2018/04/17 Python
python3实现域名查询和whois查询功能
2018/06/21 Python
python的pytest框架之命令行参数详解(上)
2019/06/27 Python
使用python画社交网络图实例代码
2019/07/10 Python
利用python实现短信和电话提醒功能的例子
2019/08/08 Python
Python3.6+selenium2.53.6自动化测试_读取excel文件的方法
2019/09/06 Python
python爬虫泛滥的解决方法详解
2020/11/25 Python
Speedo美国:澳大利亚顶尖泳衣制造商
2016/08/03 全球购物
恶搞卫生巾广告词
2014/03/18 职场文书
导游个人求职信范文
2014/03/23 职场文书
分公司总经理岗位职责
2014/07/30 职场文书
企业公益活动策划方案
2014/08/24 职场文书
业务员岗位职责范本
2015/04/03 职场文书
Python中递归以及递归遍历目录详解
2021/10/24 Python