# 表格和Admin

simplepro table基于elementui table,设置主要来自ModelAdmin,写法与原生admin一致,但是在原生的基础上增加了和减少了部分字段。注意目前table仅支持下列这些字段,但是在编辑和添加页还有用到其他字段,请参考原生admin与simpleui,simplepro是完全基于simpleui的。

# 自定义按钮

admin中的自定义actions也是支持的,也就是simpleui说说的自定义按钮。

定义方法和使用均与原生admin一致,不过simpleui在这基础上进行了扩展。可以参考自定义按钮文档

# Admin字段

字段 类型 说明
list_display tuple table显示的字段
search_fields tuple 搜索框搜索的字段
list_per_page int 每页显示的数量
list_filter array 筛选字段
list_display_links 显示连接进入编辑页的字段
fields_options dict 表格的表头字段设置
actions_show boolean 显示隐藏action,默认为True,只有显式指定为False的时候才隐藏
actions array 自定义按钮
native_render boolean 使用原生页面渲染,默认为Flase
list_filter_multiples array 3.1版本起可用,搜索下拉框多选字段,比如要在list_filter中包含才生效
top_html str 列表顶部显示的html,支持vue组件和element组件,3.1.3+ 可用
bottom_html str 列表底部显示的html,支持vue组件和element组件,3.1.3+ 可用

# top_html

在列表顶部显示的html,支持vue组件和element组件,3.1.3+ 可用

# 例子

@admin.register(ProductCategory)
class ProductCategoryAdmin(admin.ModelAdmin):
    # 显示在列表顶部的一些自定义html,可以是vue组件,会被vue渲染
    top_html = ' <el-alert title="这是顶部的" type="success"></el-alert>'

    # 也可以是方法的形式来返回html
    def get_top_html(self, request):
        return self.top_html
1
2
3
4
5
6
7
8

# 效果

# bottom_html

在列表底部显示的html,支持vue组件和element组件,3.1.3+ 可用

# 例子

@admin.register(ProductCategory)
class ProductCategoryAdmin(admin.ModelAdmin):
    # 显示在列表顶部的一些自定义html,可以是vue组件,会被vue渲染
    bottom_html = ' <el-alert title="这是底部的" type="success"></el-alert>'

    # 也可以是方法的形式来返回html
    def get_bottom_html(self, request):
        return self.top_html
1
2
3
4
5
6
7
8

# 效果

  • 字段互斥

list_display_links 字段与formatter方法互斥

如果有formatter方法,list_display_links中配置的字段将无任何作用。

# fields_options字段

admin 中字段设置,及时list_display 未定义该字段,在这里设置了也不会出错 表头字段完全遵循elementui的table文档:

https://element.eleme.cn/#/zh-CN/component/table (opens new window)

fields_options支持自定义字段的值,比如model中的自定义方法 就算自定义字段

# 属性

目前支持以下属性

字段 类型 说明
fixed str 固定列,取值 left 和right
sortable boolean 排序字段,默认为'custom'
width str 宽度,取值例如100px
min_width str 最小宽度,取值例如100px
resizable boolean 列是否可以调整宽度
class_name str 列的 className
label_class_name str 当前列标题的自定义类名
  • sortable字段

排序字段,默认为'custom',取值为: true, false, 'custom'

其中为custom的时候网络排序

取值为true,本地排序

自定义字段该值始终为false不排序

# fields_options例子

fields_options = {
        'id': {
            'fixed': 'left',
            'width': '80px',
            'align': 'center'
        },
        'create_time': {
            'fixed': 'right',
            'width': '200px',
            'align': 'left'
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12

# list_filter_multiples

下拉框多选字段,比如要在list_filter中包含才生效

# 示例


@admin.register(FilterMultiple)
class FilterMultipleAdmin(admin.ModelAdmin):
    """
    搜索框多选
    """

    list_display = ('pk', 'name', 'category')

    # list_filter要和list_filter_multiples匹配使用才有效果
    list_filter = ('category',)
    list_filter_multiples = ('category',)

1
2
3
4
5
6
7
8
9
10
11
12
13

# 效果

# 方法

字段 类型 说明
delete_queryset function 删除时触发该方法
formatter function 数据格式化
get_queryset function 获取自定义的queryset
get_list_display function 获取自定义的list_display
get_list_filter function 获取自定义的list_filter
get_actions function 获取自定义的actions
get_summaries function 获取底部统计数据
get_results function 获取返回的结果,1.2+版本生效
get_top_html function 列表顶部显示的html,支持vue组件和element组件,3.1.3+ 可用
get_bottom_html function 列表底部显示的html,支持vue组件和element组件,3.1.3+ 可用

# formatter 方法

  • 入参
字段 类型 说明
obj object 当前对象
field_name str 字段名
value object 字段值
  • 返回

返回参数为单元格显示的值,可以是html,可以是文本。

# formatter例子

def formatter(self, obj, field_name, value):
    # 这里可以对value的值进行判断,比如日期格式化等
    return value
1
2
3

# delete_queryset 说明

例子:

def delete_queryset(self, request, queryset):
    #这里可以做些自定义的处理
    pass
1
2
3
  • 返回

如果返回的是queryset,那么程序将会调用delete方法执行删除。如果返回的是None,将不会做任何动作

  • 从3.0版本开始

如果想要自己处理删除逻辑,不需要simplepro直接删除数据,可以将delete_queryset方法返回True 这样simplepro就不会执行删除动作。可以自己实现一些逻辑删除

例如:

def delete_queryset(self,request,queryset):
    queryset.filter(xxxx...).update(is_delete=False)
    return True
1
2
3

# get_queryset 说明

例子:

 def get_queryset(self, request):
        qs = super().get_queryset(request)

        return qs.filter(id__gte=1)
1
2
3
4

注意,get_queryset可以返回为None,包括pass也是返回为None。如果为None,的时候 该queryset将会被丢弃,框架将会从model中获取queryset

qs=model.objects.get_querset()
1

可以利用这个方法来控制自定义的数据权限,该方法与原生admin一致。

# get_list_display 说明

    def get_list_display(self, request):
        # 这里可以进行判断,动态返回某些字段或表头
        return self.list_display
1
2
3

# get_list_filter 说明

    def get_list_filter(self, request):
        # 这里可以进行判断,动态返回list_filter
        return self.list_filter
1
2
3

# get_actions 说明

    def get_actions(self, request):
        # 这里可以进行判断,动态返回actions
        actions = super(EmployeAdmin, self).get_actions(request)
    return actions
1
2
3
4

# get_summaries 说明

在modeladmin中加入该方法后,会自动在表格底部增加一列合计列。 可以用request来控制动态显示,也可以直接使用带有搜索条件的queryset,该queryset是列表数据的深拷贝对象,不带排序和分页。

Demo1.

    # 动态统计,Simple Pro独有功能
    def get_summaries(self, request, queryset):
        # 自定义统计,可以根据request的页面 来统计当前页的数据,queryset 为深拷贝对象,如果传入的话 可能会影响列表的数据
        # 返回的数据 为数组,对应列表的每一列
        # 不支持html

        # 如果想根据人员权限来动态展示,可以直接返回不同的数组,或者返回为None,为None的时候,不显示统计列

        # 如果想统计满足当前搜索条件的数据的话 ,可以直接使用queryset.来进行统计
        if request.POST.get('current_page') == '2':
            return None
        else:
            # 需要有空字符串占位
            return ('合计', '321', '1213123', '123123', '', '', '', '测试')
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Demo2.

    # 动态统计,Simple Pro独有功能
    def get_summaries(self, request, queryset):
        # 如果想统计满足当前搜索条件的数据的话 ,可以直接使用queryset.来进行统计
        # queryset.aggregate(total=Sum('money')).get('total')

        a = "¥{}".format(Record.objects.aggregate(total=Sum('money')).get('total'))
        print(a)
        # 需要有空字符串占位
        return ('', '数据合计', '', '', a, '2020年01月14日')
1
2
3
4
5
6
7
8
9

界面效果:

# get_results 获取返回结果

该方法在simplepro 1.2及以上版本中生效,用于处理最终的结果集。

例子:


    # 注意:
    # 这里的queryset 改变过滤条件将不会影响返回的结果。如果需要操作queryset,
    # 请在get_queryset方法中进行
    # results 将会是一个 dict list,而不是对象,获取属性 需要用get

    def get_results(self, results, request, queryset):
        print('处理结果集')
        new_results=[]

        for item in results:
            if 'aa' in item:
                print(item.get('aa'))
                item['aa']='这是一个测试属性'

            new_results.append(item)

        return new_results
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Media 自定义引入js和css

Media 遵从原生django admin的写法,并且处理也是django实现,simplepro未做任何文件处理,只做引入动作。

# 例子


@admin.register(Department)
class DepartmentAdmin(admin.ModelAdmin):

    class Media:
        js=('aa.js','bb.js')
        css=('dd.css','cc.css')

1
2
3
4
5
6
7
8

在页面解析的时候 会调用下列方式进行引入

<script type="text/javascript" src="{% static 'aa.js'%}">
1

# 核心源码

  • 引入js部分:
 {% if media.js %}
    {% for js in media.js %}
    <script type="text/javascript" src="{% static js %}"></script>
    {% endfor %}
{% endif %}
1
2
3
4
5
  • 引入css部分:
{% if media.css %}
    {% for css in media.css %}
    <link rel="stylesheet" href="{% static css %}">
    {% endfor %}
{% endif %}
1
2
3
4
5

在通过引入自己的js和css之后,可以对页面进行扩展,调用simplepro的js sdk 可以实现意想不到的效果,比如表格format,添加自定义按钮,拦截按钮事件等。具体请看jssdk

# 常见问题

# 1. 权限

增删改查按钮,可以利用系统自带的权限进行控制,对于自定义的action,也支持权限控制。 请参考文档:权限文档

# 2. 数据权限

对于数据级别的权限,不属于框架的范畴,这是需要自己在业务逻辑的处理上进行控制,可以利用ModelAdmin中的get_queryset方法来进行数据的过滤。

例如:


class SimpleAdmin(...):

    def get_queryset(request,qs):
        qs.filter(user__id=123,type_id=321)
        return qs

1
2
3
4
5
6
7
更新时间: 10/30/2021, 10:10:50 PM