hadmin


Namehadmin JSON
Version 1.2.1 PyPI version JSON
download
home_pagehttps://github.com/spirits001/python-HAdmin
Summary针对自动化给予前端配置文件的DRF封装
upload_time2024-01-30 11:19:35
maintainer
docs_urlNone
author代码厨子
requires_python>=3
license
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # HAdmin后端对DRF封装

我想实现一个这样的理想国:

比xadmin漂亮;比xadmin强大;前后端分离;基于Django和DRF;智能化配置。

以上几点,是我们对HAdmin的设想,设想这样的后端能够相对自动化输出接口,让前端能够根据配置文件认识输出的标准数据结构,从而进行渲染。

于是,初步版本的HAdmin上线了。

### 特别说明

这个模块只是帮助构建给前端的配置信息,让前端方便进行对应渲染,并不是给前端输送代码!

这个请大家一定要理解清楚,这里仅仅是帮助规范了配置信息结构而已。

# 快速开始

## 安装

```bash
pip install hadmin
```

## 使用方式

```python
from rest_framework import viewsets
from hadmin import mixins


class CustomConfigViewSet(mixins.PageConfigMixin, viewsets.GenericViewSet):
    list_class = CustomListSerializer
    filter_class = CustomFilter
    create_class = CustomCreateSerializer
    read_class = CustomReadSerializer
    extra = {}
```

其实,就是用HAdmin下的mixins替代rest_framework下的mixins

并且,增加了一个PageConfigMixin方法,这个方法包含了四种配置文件的输出方式,分别是:

list_class 列表的配置信息

filter_class 筛选器的配置信息

create_class 创建数据表单的配置信息

read_class 读取最终数据的配置信息

extra 是额外扩展的数据,可以是字典或者列表等任意可以转换成json的值,会原样递送到前端,用于前端渲染特殊情况下使用,非必填,根据需要使用

每个对应的都是序列化器的的类,序列化器建议每个方法用不同类,这样可以自由定义。

每个序列化器类的元数据可以增加一个custom字典,以便进行解析。

输出到前端的数据样例:

```json
{
	"filter": {
		"base": [{
			"label": "手机号",
			"method": "input",
			"default": "",
			"url": "",
			"limit": 1,
			"span": 6,
			"key": "mobile"
		}, {
			"label": "姓名",
			"method": "input",
			"default": "",
			"url": "",
			"limit": 1,
			"span": 6,
			"key": "name"
		}, {
			"label": "姓名",
			"method": "input",
			"default": "",
			"url": "",
			"limit": 1,
			"span": 6,
			"key": "desc"
		}, {
			"label": "新房客源",
			"method": "select",
			"default": "",
			"url": "",
			"limit": 1,
			"span": 6,
			"key": "new",
			"options": [{
				"id": "-1000",
				"title": "不限"
			}, {
				"id": "true",
				"title": "是"
			}, {
				"id": "false",
				"title": "否"
			}, {
				"id": "isnull",
				"title": "未填写"
			}]
		}, {
			"label": "二手房客源",
			"method": "select",
			"default": "",
			"url": "",
			"limit": 1,
			"span": 6,
			"key": "old",
			"options": [{
				"id": "-1000",
				"title": "不限"
			}, {
				"id": "true",
				"title": "是"
			}, {
				"id": "false",
				"title": "否"
			}, {
				"id": "isnull",
				"title": "未填写"
			}]
		}, {
			"label": "租房客源",
			"method": "select",
			"default": "",
			"url": "",
			"limit": 1,
			"span": 6,
			"key": "rent",
			"options": [{
				"id": "-1000",
				"title": "不限"
			}, {
				"id": "true",
				"title": "是"
			}, {
				"id": "false",
				"title": "否"
			}, {
				"id": "isnull",
				"title": "未填写"
			}]
		}],
		"adv": [],
		"height": 100,
		"fields": {
			"mobile": "",
			"name": "",
			"desc": "",
			"new": "",
			"old": "",
			"rent": ""
		}
	},
	"create": {
		"fields": {
			"master": null,
			"region": null,
			"admins": [],
			"mobile": "",
			"name": "",
			"new": false,
			"old": false,
			"rent": false,
			"desc": "",
			"custom": []
		},
		"inlines": {
			"custom": {
				"label": "跟踪记录",
				"create": {
					"fields": {
						"custom": null,
						"date": null,
						"body": "",
						"result": "",
						"image": null,
						"file": null
					},
					"detail": [{
						"label": "客源",
						"help_text": null,
						"field_name": "custom",
						"required": true,
						"type": "PrimaryKeyRelatedField",
						"rules": [{
							"required": true,
							"message": "该字段是必填项。"
						}],
						"choices": [{
							"value": 13,
							"label": "18888888885"
						}, {
							"value": 12,
							"label": "18888888884"
						}, {
							"value": 11,
							"label": "18888888883"
						}, {
							"value": 10,
							"label": "18888888882"
						}, {
							"value": 8,
							"label": "13999999990"
						}, {
							"value": 7,
							"label": "13999999994"
						}, {
							"value": 6,
							"label": "13999999995"
						}, {
							"value": 5,
							"label": "13999999996"
						}, {
							"value": 4,
							"label": "13999999997"
						}, {
							"value": 3,
							"label": "13999999998"
						}, {
							"value": 2,
							"label": "13999999999"
						}, {
							"value": 1,
							"label": "13888888888"
						}],
						"choices_apis": [],
						"method": "",
						"max_length": 0,
						"precision": null,
						"field": "ForeignKey"
					}, {
						"label": "时间",
						"help_text": null,
						"field_name": "date",
						"required": true,
						"type": "DateField",
						"rules": [{
							"required": true,
							"message": "该字段是必填项。"
						}],
						"choices": [],
						"choices_apis": [],
						"method": "",
						"max_length": 0,
						"precision": null,
						"field": "DateField"
					}, {
						"label": "内容",
						"help_text": null,
						"field_name": "body",
						"required": true,
						"type": "CharField",
						"rules": [{
							"required": true,
							"message": "该字段是必填项。"
						}],
						"choices": [],
						"choices_apis": [],
						"method": "",
						"max_length": 10000,
						"precision": null,
						"field": "TextField"
					}, {
						"label": "结果",
						"help_text": null,
						"field_name": "result",
						"required": false,
						"type": "CharField",
						"rules": [],
						"choices": [],
						"choices_apis": [],
						"method": "",
						"max_length": 10000,
						"precision": null,
						"field": "TextField"
					}, {
						"label": "图片",
						"help_text": null,
						"field_name": "image",
						"required": false,
						"type": "ImageField",
						"rules": [],
						"choices": [],
						"choices_apis": [],
						"method": "",
						"max_length": 100,
						"precision": null,
						"field": "ImageField"
					}, {
						"label": "附件",
						"help_text": null,
						"field_name": "file",
						"required": false,
						"type": "FileField",
						"rules": [],
						"choices": [],
						"choices_apis": [],
						"method": "",
						"max_length": 100,
						"precision": null,
						"field": "FileField"
					}],
					"inlines": {},
					"tabs": []
				},
				"limit": 10,
				"api": "/admin/user/track/data/"
			}
		},
		"detail": [{
			"label": "主理人",
			"help_text": null,
			"field_name": "master",
			"required": false,
			"type": "PrimaryKeyRelatedField",
			"rules": [],
			"choices": [{
				"value": 1,
				"label": "hofeng"
			}, {
				"value": 13,
				"label": "18961330033"
			}, {
				"value": 83,
				"label": "shanghai001"
			}, {
				"value": 84,
				"label": "shanghai002"
			}, {
				"value": 85,
				"label": "shanghai003"
			}, {
				"value": 86,
				"label": "suqian001"
			}],
			"choices_apis": [],
			"method": "",
			"max_length": 0,
			"precision": null,
			"field": "ForeignKey"
		}, {
			"label": "地区",
			"help_text": null,
			"field_name": "region",
			"required": true,
			"type": "PrimaryKeyRelatedField",
			"rules": [{
				"required": true,
				"message": "该字段是必填项。"
			}],
			"choices": [{
				"value": 1,
				"label": "上海【310000】"
			}, {
				"value": 21,
				"label": "宿迁【321300】"
			}, {
				"value": 34,
				"label": "盐城【320900】"
			}],
			"choices_apis": [],
			"method": "",
			"max_length": 0,
			"precision": null,
			"field": "ForeignKey"
		}, {
			"label": "协作人",
			"help_text": null,
			"field_name": "admins",
			"required": false,
			"type": "ManyRelatedField",
			"rules": [],
			"choices": [{
				"value": 1,
				"label": "hofeng"
			}, {
				"value": 13,
				"label": "18961330033"
			}, {
				"value": 83,
				"label": "shanghai001"
			}, {
				"value": 84,
				"label": "shanghai002"
			}, {
				"value": 85,
				"label": "shanghai003"
			}, {
				"value": 86,
				"label": "suqian001"
			}],
			"choices_apis": [],
			"method": "",
			"max_length": 0,
			"precision": null,
			"field": "ManyToManyField"
		}, {
			"label": "手机号",
			"help_text": "客源手机号",
			"field_name": "mobile",
			"required": true,
			"type": "CharField",
			"rules": [{
				"required": true,
				"message": "该字段是必填项。"
			}],
			"choices": [],
			"choices_apis": [],
			"method": "",
			"max_length": 11,
			"precision": null,
			"field": "CharField"
		}, {
			"label": "姓名",
			"help_text": null,
			"field_name": "name",
			"required": false,
			"type": "CharField",
			"rules": [],
			"choices": [],
			"choices_apis": [],
			"method": "",
			"max_length": 32,
			"precision": null,
			"field": "CharField"
		}, {
			"label": "新房客源",
			"help_text": null,
			"field_name": "new",
			"required": false,
			"type": "BooleanField",
			"rules": [],
			"choices": [],
			"choices_apis": [],
			"method": "",
			"max_length": 0,
			"precision": null,
			"field": "BooleanField"
		}, {
			"label": "二手房客源",
			"help_text": null,
			"field_name": "old",
			"required": false,
			"type": "BooleanField",
			"rules": [],
			"choices": [],
			"choices_apis": [],
			"method": "",
			"max_length": 0,
			"precision": null,
			"field": "BooleanField"
		}, {
			"label": "租房客源",
			"help_text": null,
			"field_name": "rent",
			"required": false,
			"type": "BooleanField",
			"rules": [],
			"choices": [],
			"choices_apis": [],
			"method": "",
			"max_length": 0,
			"precision": null,
			"field": "BooleanField"
		}, {
			"label": "简要说明",
			"help_text": null,
			"field_name": "desc",
			"required": false,
			"type": "CharField",
			"rules": [],
			"choices": [],
			"choices_apis": [],
			"method": "",
			"max_length": 2000,
			"precision": null,
			"field": "TextField"
		}],
		"tabs": []
	},
	"list": [{
		"label": "ID",
		"field_name": "id",
		"type": "IntegerField",
		"field": "AutoField",
		"width": "80"
	}, {
		"label": "手机号",
		"field_name": "mobile",
		"type": "CharField",
		"field": "CharField"
	}, {
		"label": "姓名",
		"field_name": "name",
		"type": "CharField",
		"field": "CharField"
	}, {
		"label": "主理人",
		"field_name": "master",
		"type": "StringRelatedField",
		"field": "ForeignKey"
	}, {
		"label": "新房客源",
		"field_name": "new",
		"type": "BooleanField",
		"field": "BooleanField"
	}, {
		"label": "二手房客源",
		"field_name": "old",
		"type": "BooleanField",
		"field": "BooleanField"
	}, {
		"label": "租房客源",
		"field_name": "rent",
		"type": "BooleanField",
		"field": "BooleanField"
	}, {
		"label": "添加时间",
		"field_name": "add_time",
		"type": "DateTimeField",
		"field": "DateTimeField"
	}],
	"read": [{
		"label": "主理人",
		"field_name": "master",
		"type": "StringRelatedField"
	}, {
		"label": "地区",
		"field_name": "region",
		"type": "StringRelatedField"
	}, {
		"label": "协作人",
		"field_name": "admins",
		"type": "ManyRelatedField"
	}, {
		"label": "添加时间",
		"field_name": "add_time",
		"type": "DateTimeField"
	}, {
		"label": "手机号",
		"field_name": "mobile",
		"type": "CharField"
	}, {
		"label": "姓名",
		"field_name": "name",
		"type": "CharField"
	}, {
		"label": "新房客源",
		"field_name": "new",
		"type": "BooleanField"
	}, {
		"label": "二手房客源",
		"field_name": "old",
		"type": "BooleanField"
	}, {
		"label": "租房客源",
		"field_name": "rent",
		"type": "BooleanField"
	}, {
		"label": "简要说明",
		"field_name": "desc",
		"type": "CharField"
	}],
	"extra": null
}
```

下面是具体的使用方法

### list_class

```python
class CustomListSerializer(serializers.ModelSerializer):
    master = serializers.StringRelatedField()
    add_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')

    class Meta:
        model = Custom
        fields = ["id", "mobile", "name", "master", "new", "old", "rent", "add_time"]
        custom = {
            "id": {'width': '80'}
        }
```

这是一个典型的列表读取的序列化器,元数据中规定的输出字段,新增的custom字典表明某个字段的特别约定。

字典的健名用字段名表示定义某个字段;

value值是一个字典,健名自己定义,反馈到前端后,前端方便进行解析。

建议保留width,label这类字段,总之,这里定义什么,前端就会收到什么,然后前端进行渲染。

输出到前端后,对应参数健名为:list

### filter_class

作为筛选器,要定义每个筛选项,这是没办法避免的,例如:

```python
class CustomFilter(django_filters.rest_framework.FilterSet):
    mobile = django_filters.CharFilter(method='keyword_filter', help_text="手机号")
    name = django_filters.CharFilter(method='keyword_filter', help_text="姓名")
    desc = django_filters.CharFilter(method='keyword_filter', help_text="说明")
    new = django_filters.BooleanFilter(method='common_filter', help_text="新房客源", label={'options': get_easy_bool()})
    old = django_filters.BooleanFilter(method='common_filter', help_text="二手房客源", label={'options': get_easy_bool()})
    rent = django_filters.BooleanFilter(method='common_filter', help_text="租房客源", label={'options': get_easy_bool()})
```

以上就是对筛选器的定义,对项的定义,放在label进行定义,选择类的给options值,help_text是显示出来的名称

输出到前端后,对应参数健名为:filter

### create_class

创建类的输出,是为了前端自动构造提交表单而定,序列化器写法没有特别,和list一样,可以在元数据中增加一个custom字典,对应把每个字段的特别要求输送到前端。

和其他不同的是,create的Meta下可以额外增加一个tabs,结构为:

```python
tabs = [{
    'label': '基本信息',
    'fields': ['mobile', 'name', 'region', 'desc']
}, {
    'label': '权限配置',
    'fields': ['master', 'admins', 'new', 'old', 'rent']
}]
```

另外,还增加了一个inlines的数据,结构如下

```python
inlines = {
    'custom': {
        'class': TrackCreateSerializer,
        'api': '/admin/user/track/data/',
        'limit': 10
    }
}
```
说明:健名是作为主键的字段名,也就是其他子数据的主字段名;class是这个子数据创建的序列化器;api是创建接口;limit是一次最多多少个

这样设定,前端就可以得到这个tabs,可以用于添加表单分步执行。

输出到前端后,对应参数健名为:create

### read_class

读取详细内容的序列化器,要注意的是最好不要构建外键对象,而是要用serializers.StringRelatedField()方法把外键进行文本化,这样才能在前端正常显示。

输出到前端后,对应参数健名为:read

### extra

这个用于额外给前端一个扩展的数据字段,可以设定一切能够转为json的数据,用于自己定义与前端的协议

输入到前端后,对应参数健名为:extra

# 版本历史

1.0.5 修复外键选择项过多的问题,添加choices_limit参数,默认超过30个选项就不在从choices里自动取选择项,请在custom里对字段检索方式进行配置

1.0.6 对隐藏字段支持屏蔽,同时修复了一下可能出现的bug;增加了数字字段的小数点长度判断

1.0.7 增加inline模式的配置数据输出,规则见create_class说明

1.0.8 优化了代码,聚类了函数;增加list和read方式下的参数,为patch字段级提供方便

1.0.9 修正inlines的bug

1.0.10 修正create的bug

1.0.11 增加default值的输出

1.0.12 修复bug

1.1.0  增加update

1.1.1  修改默认tabs

1.1.2  修复bug

1.1.3  修复bug

1.1.4  inlines内增加filter参数

1.2.0 新增工具包,详见hadmin.utils

1.2.1 修复list方法上的bug

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/spirits001/python-HAdmin",
    "name": "hadmin",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3",
    "maintainer_email": "",
    "keywords": "",
    "author": "\u4ee3\u7801\u53a8\u5b50",
    "author_email": "15755153@qq.com",
    "download_url": "https://files.pythonhosted.org/packages/fc/61/dd7ecb42f3c27b25ee67b115b62944a038f3f1d741a2303c2cd87d6243fc/hadmin-1.2.1.tar.gz",
    "platform": null,
    "description": "# HAdmin\u540e\u7aef\u5bf9DRF\u5c01\u88c5\n\n\u6211\u60f3\u5b9e\u73b0\u4e00\u4e2a\u8fd9\u6837\u7684\u7406\u60f3\u56fd\uff1a\n\n\u6bd4xadmin\u6f02\u4eae\uff1b\u6bd4xadmin\u5f3a\u5927\uff1b\u524d\u540e\u7aef\u5206\u79bb\uff1b\u57fa\u4e8eDjango\u548cDRF\uff1b\u667a\u80fd\u5316\u914d\u7f6e\u3002\n\n\u4ee5\u4e0a\u51e0\u70b9\uff0c\u662f\u6211\u4eec\u5bf9HAdmin\u7684\u8bbe\u60f3\uff0c\u8bbe\u60f3\u8fd9\u6837\u7684\u540e\u7aef\u80fd\u591f\u76f8\u5bf9\u81ea\u52a8\u5316\u8f93\u51fa\u63a5\u53e3\uff0c\u8ba9\u524d\u7aef\u80fd\u591f\u6839\u636e\u914d\u7f6e\u6587\u4ef6\u8ba4\u8bc6\u8f93\u51fa\u7684\u6807\u51c6\u6570\u636e\u7ed3\u6784\uff0c\u4ece\u800c\u8fdb\u884c\u6e32\u67d3\u3002\n\n\u4e8e\u662f\uff0c\u521d\u6b65\u7248\u672c\u7684HAdmin\u4e0a\u7ebf\u4e86\u3002\n\n### \u7279\u522b\u8bf4\u660e\n\n\u8fd9\u4e2a\u6a21\u5757\u53ea\u662f\u5e2e\u52a9\u6784\u5efa\u7ed9\u524d\u7aef\u7684\u914d\u7f6e\u4fe1\u606f\uff0c\u8ba9\u524d\u7aef\u65b9\u4fbf\u8fdb\u884c\u5bf9\u5e94\u6e32\u67d3\uff0c\u5e76\u4e0d\u662f\u7ed9\u524d\u7aef\u8f93\u9001\u4ee3\u7801\uff01\n\n\u8fd9\u4e2a\u8bf7\u5927\u5bb6\u4e00\u5b9a\u8981\u7406\u89e3\u6e05\u695a\uff0c\u8fd9\u91cc\u4ec5\u4ec5\u662f\u5e2e\u52a9\u89c4\u8303\u4e86\u914d\u7f6e\u4fe1\u606f\u7ed3\u6784\u800c\u5df2\u3002\n\n# \u5feb\u901f\u5f00\u59cb\n\n## \u5b89\u88c5\n\n```bash\npip install hadmin\n```\n\n## \u4f7f\u7528\u65b9\u5f0f\n\n```python\nfrom rest_framework import viewsets\nfrom hadmin import mixins\n\n\nclass CustomConfigViewSet(mixins.PageConfigMixin, viewsets.GenericViewSet):\n    list_class = CustomListSerializer\n    filter_class = CustomFilter\n    create_class = CustomCreateSerializer\n    read_class = CustomReadSerializer\n    extra = {}\n```\n\n\u5176\u5b9e\uff0c\u5c31\u662f\u7528HAdmin\u4e0b\u7684mixins\u66ff\u4ee3rest_framework\u4e0b\u7684mixins\n\n\u5e76\u4e14\uff0c\u589e\u52a0\u4e86\u4e00\u4e2aPageConfigMixin\u65b9\u6cd5\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u5305\u542b\u4e86\u56db\u79cd\u914d\u7f6e\u6587\u4ef6\u7684\u8f93\u51fa\u65b9\u5f0f\uff0c\u5206\u522b\u662f\uff1a\n\nlist_class \u5217\u8868\u7684\u914d\u7f6e\u4fe1\u606f\n\nfilter_class \u7b5b\u9009\u5668\u7684\u914d\u7f6e\u4fe1\u606f\n\ncreate_class \u521b\u5efa\u6570\u636e\u8868\u5355\u7684\u914d\u7f6e\u4fe1\u606f\n\nread_class \u8bfb\u53d6\u6700\u7ec8\u6570\u636e\u7684\u914d\u7f6e\u4fe1\u606f\n\nextra \u662f\u989d\u5916\u6269\u5c55\u7684\u6570\u636e\uff0c\u53ef\u4ee5\u662f\u5b57\u5178\u6216\u8005\u5217\u8868\u7b49\u4efb\u610f\u53ef\u4ee5\u8f6c\u6362\u6210json\u7684\u503c\uff0c\u4f1a\u539f\u6837\u9012\u9001\u5230\u524d\u7aef\uff0c\u7528\u4e8e\u524d\u7aef\u6e32\u67d3\u7279\u6b8a\u60c5\u51b5\u4e0b\u4f7f\u7528\uff0c\u975e\u5fc5\u586b\uff0c\u6839\u636e\u9700\u8981\u4f7f\u7528\n\n\u6bcf\u4e2a\u5bf9\u5e94\u7684\u90fd\u662f\u5e8f\u5217\u5316\u5668\u7684\u7684\u7c7b\uff0c\u5e8f\u5217\u5316\u5668\u5efa\u8bae\u6bcf\u4e2a\u65b9\u6cd5\u7528\u4e0d\u540c\u7c7b\uff0c\u8fd9\u6837\u53ef\u4ee5\u81ea\u7531\u5b9a\u4e49\u3002\n\n\u6bcf\u4e2a\u5e8f\u5217\u5316\u5668\u7c7b\u7684\u5143\u6570\u636e\u53ef\u4ee5\u589e\u52a0\u4e00\u4e2acustom\u5b57\u5178\uff0c\u4ee5\u4fbf\u8fdb\u884c\u89e3\u6790\u3002\n\n\u8f93\u51fa\u5230\u524d\u7aef\u7684\u6570\u636e\u6837\u4f8b\uff1a\n\n```json\n{\n\t\"filter\": {\n\t\t\"base\": [{\n\t\t\t\"label\": \"\u624b\u673a\u53f7\",\n\t\t\t\"method\": \"input\",\n\t\t\t\"default\": \"\",\n\t\t\t\"url\": \"\",\n\t\t\t\"limit\": 1,\n\t\t\t\"span\": 6,\n\t\t\t\"key\": \"mobile\"\n\t\t}, {\n\t\t\t\"label\": \"\u59d3\u540d\",\n\t\t\t\"method\": \"input\",\n\t\t\t\"default\": \"\",\n\t\t\t\"url\": \"\",\n\t\t\t\"limit\": 1,\n\t\t\t\"span\": 6,\n\t\t\t\"key\": \"name\"\n\t\t}, {\n\t\t\t\"label\": \"\u59d3\u540d\",\n\t\t\t\"method\": \"input\",\n\t\t\t\"default\": \"\",\n\t\t\t\"url\": \"\",\n\t\t\t\"limit\": 1,\n\t\t\t\"span\": 6,\n\t\t\t\"key\": \"desc\"\n\t\t}, {\n\t\t\t\"label\": \"\u65b0\u623f\u5ba2\u6e90\",\n\t\t\t\"method\": \"select\",\n\t\t\t\"default\": \"\",\n\t\t\t\"url\": \"\",\n\t\t\t\"limit\": 1,\n\t\t\t\"span\": 6,\n\t\t\t\"key\": \"new\",\n\t\t\t\"options\": [{\n\t\t\t\t\"id\": \"-1000\",\n\t\t\t\t\"title\": \"\u4e0d\u9650\"\n\t\t\t}, {\n\t\t\t\t\"id\": \"true\",\n\t\t\t\t\"title\": \"\u662f\"\n\t\t\t}, {\n\t\t\t\t\"id\": \"false\",\n\t\t\t\t\"title\": \"\u5426\"\n\t\t\t}, {\n\t\t\t\t\"id\": \"isnull\",\n\t\t\t\t\"title\": \"\u672a\u586b\u5199\"\n\t\t\t}]\n\t\t}, {\n\t\t\t\"label\": \"\u4e8c\u624b\u623f\u5ba2\u6e90\",\n\t\t\t\"method\": \"select\",\n\t\t\t\"default\": \"\",\n\t\t\t\"url\": \"\",\n\t\t\t\"limit\": 1,\n\t\t\t\"span\": 6,\n\t\t\t\"key\": \"old\",\n\t\t\t\"options\": [{\n\t\t\t\t\"id\": \"-1000\",\n\t\t\t\t\"title\": \"\u4e0d\u9650\"\n\t\t\t}, {\n\t\t\t\t\"id\": \"true\",\n\t\t\t\t\"title\": \"\u662f\"\n\t\t\t}, {\n\t\t\t\t\"id\": \"false\",\n\t\t\t\t\"title\": \"\u5426\"\n\t\t\t}, {\n\t\t\t\t\"id\": \"isnull\",\n\t\t\t\t\"title\": \"\u672a\u586b\u5199\"\n\t\t\t}]\n\t\t}, {\n\t\t\t\"label\": \"\u79df\u623f\u5ba2\u6e90\",\n\t\t\t\"method\": \"select\",\n\t\t\t\"default\": \"\",\n\t\t\t\"url\": \"\",\n\t\t\t\"limit\": 1,\n\t\t\t\"span\": 6,\n\t\t\t\"key\": \"rent\",\n\t\t\t\"options\": [{\n\t\t\t\t\"id\": \"-1000\",\n\t\t\t\t\"title\": \"\u4e0d\u9650\"\n\t\t\t}, {\n\t\t\t\t\"id\": \"true\",\n\t\t\t\t\"title\": \"\u662f\"\n\t\t\t}, {\n\t\t\t\t\"id\": \"false\",\n\t\t\t\t\"title\": \"\u5426\"\n\t\t\t}, {\n\t\t\t\t\"id\": \"isnull\",\n\t\t\t\t\"title\": \"\u672a\u586b\u5199\"\n\t\t\t}]\n\t\t}],\n\t\t\"adv\": [],\n\t\t\"height\": 100,\n\t\t\"fields\": {\n\t\t\t\"mobile\": \"\",\n\t\t\t\"name\": \"\",\n\t\t\t\"desc\": \"\",\n\t\t\t\"new\": \"\",\n\t\t\t\"old\": \"\",\n\t\t\t\"rent\": \"\"\n\t\t}\n\t},\n\t\"create\": {\n\t\t\"fields\": {\n\t\t\t\"master\": null,\n\t\t\t\"region\": null,\n\t\t\t\"admins\": [],\n\t\t\t\"mobile\": \"\",\n\t\t\t\"name\": \"\",\n\t\t\t\"new\": false,\n\t\t\t\"old\": false,\n\t\t\t\"rent\": false,\n\t\t\t\"desc\": \"\",\n\t\t\t\"custom\": []\n\t\t},\n\t\t\"inlines\": {\n\t\t\t\"custom\": {\n\t\t\t\t\"label\": \"\u8ddf\u8e2a\u8bb0\u5f55\",\n\t\t\t\t\"create\": {\n\t\t\t\t\t\"fields\": {\n\t\t\t\t\t\t\"custom\": null,\n\t\t\t\t\t\t\"date\": null,\n\t\t\t\t\t\t\"body\": \"\",\n\t\t\t\t\t\t\"result\": \"\",\n\t\t\t\t\t\t\"image\": null,\n\t\t\t\t\t\t\"file\": null\n\t\t\t\t\t},\n\t\t\t\t\t\"detail\": [{\n\t\t\t\t\t\t\"label\": \"\u5ba2\u6e90\",\n\t\t\t\t\t\t\"help_text\": null,\n\t\t\t\t\t\t\"field_name\": \"custom\",\n\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\"type\": \"PrimaryKeyRelatedField\",\n\t\t\t\t\t\t\"rules\": [{\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"message\": \"\u8be5\u5b57\u6bb5\u662f\u5fc5\u586b\u9879\u3002\"\n\t\t\t\t\t\t}],\n\t\t\t\t\t\t\"choices\": [{\n\t\t\t\t\t\t\t\"value\": 13,\n\t\t\t\t\t\t\t\"label\": \"18888888885\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 12,\n\t\t\t\t\t\t\t\"label\": \"18888888884\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 11,\n\t\t\t\t\t\t\t\"label\": \"18888888883\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 10,\n\t\t\t\t\t\t\t\"label\": \"18888888882\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 8,\n\t\t\t\t\t\t\t\"label\": \"13999999990\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 7,\n\t\t\t\t\t\t\t\"label\": \"13999999994\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 6,\n\t\t\t\t\t\t\t\"label\": \"13999999995\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 5,\n\t\t\t\t\t\t\t\"label\": \"13999999996\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 4,\n\t\t\t\t\t\t\t\"label\": \"13999999997\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 3,\n\t\t\t\t\t\t\t\"label\": \"13999999998\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 2,\n\t\t\t\t\t\t\t\"label\": \"13999999999\"\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\"value\": 1,\n\t\t\t\t\t\t\t\"label\": \"13888888888\"\n\t\t\t\t\t\t}],\n\t\t\t\t\t\t\"choices_apis\": [],\n\t\t\t\t\t\t\"method\": \"\",\n\t\t\t\t\t\t\"max_length\": 0,\n\t\t\t\t\t\t\"precision\": null,\n\t\t\t\t\t\t\"field\": \"ForeignKey\"\n\t\t\t\t\t}, {\n\t\t\t\t\t\t\"label\": \"\u65f6\u95f4\",\n\t\t\t\t\t\t\"help_text\": null,\n\t\t\t\t\t\t\"field_name\": \"date\",\n\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\"type\": \"DateField\",\n\t\t\t\t\t\t\"rules\": [{\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"message\": \"\u8be5\u5b57\u6bb5\u662f\u5fc5\u586b\u9879\u3002\"\n\t\t\t\t\t\t}],\n\t\t\t\t\t\t\"choices\": [],\n\t\t\t\t\t\t\"choices_apis\": [],\n\t\t\t\t\t\t\"method\": \"\",\n\t\t\t\t\t\t\"max_length\": 0,\n\t\t\t\t\t\t\"precision\": null,\n\t\t\t\t\t\t\"field\": \"DateField\"\n\t\t\t\t\t}, {\n\t\t\t\t\t\t\"label\": \"\u5185\u5bb9\",\n\t\t\t\t\t\t\"help_text\": null,\n\t\t\t\t\t\t\"field_name\": \"body\",\n\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\"type\": \"CharField\",\n\t\t\t\t\t\t\"rules\": [{\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"message\": \"\u8be5\u5b57\u6bb5\u662f\u5fc5\u586b\u9879\u3002\"\n\t\t\t\t\t\t}],\n\t\t\t\t\t\t\"choices\": [],\n\t\t\t\t\t\t\"choices_apis\": [],\n\t\t\t\t\t\t\"method\": \"\",\n\t\t\t\t\t\t\"max_length\": 10000,\n\t\t\t\t\t\t\"precision\": null,\n\t\t\t\t\t\t\"field\": \"TextField\"\n\t\t\t\t\t}, {\n\t\t\t\t\t\t\"label\": \"\u7ed3\u679c\",\n\t\t\t\t\t\t\"help_text\": null,\n\t\t\t\t\t\t\"field_name\": \"result\",\n\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\"type\": \"CharField\",\n\t\t\t\t\t\t\"rules\": [],\n\t\t\t\t\t\t\"choices\": [],\n\t\t\t\t\t\t\"choices_apis\": [],\n\t\t\t\t\t\t\"method\": \"\",\n\t\t\t\t\t\t\"max_length\": 10000,\n\t\t\t\t\t\t\"precision\": null,\n\t\t\t\t\t\t\"field\": \"TextField\"\n\t\t\t\t\t}, {\n\t\t\t\t\t\t\"label\": \"\u56fe\u7247\",\n\t\t\t\t\t\t\"help_text\": null,\n\t\t\t\t\t\t\"field_name\": \"image\",\n\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\"type\": \"ImageField\",\n\t\t\t\t\t\t\"rules\": [],\n\t\t\t\t\t\t\"choices\": [],\n\t\t\t\t\t\t\"choices_apis\": [],\n\t\t\t\t\t\t\"method\": \"\",\n\t\t\t\t\t\t\"max_length\": 100,\n\t\t\t\t\t\t\"precision\": null,\n\t\t\t\t\t\t\"field\": \"ImageField\"\n\t\t\t\t\t}, {\n\t\t\t\t\t\t\"label\": \"\u9644\u4ef6\",\n\t\t\t\t\t\t\"help_text\": null,\n\t\t\t\t\t\t\"field_name\": \"file\",\n\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\"type\": \"FileField\",\n\t\t\t\t\t\t\"rules\": [],\n\t\t\t\t\t\t\"choices\": [],\n\t\t\t\t\t\t\"choices_apis\": [],\n\t\t\t\t\t\t\"method\": \"\",\n\t\t\t\t\t\t\"max_length\": 100,\n\t\t\t\t\t\t\"precision\": null,\n\t\t\t\t\t\t\"field\": \"FileField\"\n\t\t\t\t\t}],\n\t\t\t\t\t\"inlines\": {},\n\t\t\t\t\t\"tabs\": []\n\t\t\t\t},\n\t\t\t\t\"limit\": 10,\n\t\t\t\t\"api\": \"/admin/user/track/data/\"\n\t\t\t}\n\t\t},\n\t\t\"detail\": [{\n\t\t\t\"label\": \"\u4e3b\u7406\u4eba\",\n\t\t\t\"help_text\": null,\n\t\t\t\"field_name\": \"master\",\n\t\t\t\"required\": false,\n\t\t\t\"type\": \"PrimaryKeyRelatedField\",\n\t\t\t\"rules\": [],\n\t\t\t\"choices\": [{\n\t\t\t\t\"value\": 1,\n\t\t\t\t\"label\": \"hofeng\"\n\t\t\t}, {\n\t\t\t\t\"value\": 13,\n\t\t\t\t\"label\": \"18961330033\"\n\t\t\t}, {\n\t\t\t\t\"value\": 83,\n\t\t\t\t\"label\": \"shanghai001\"\n\t\t\t}, {\n\t\t\t\t\"value\": 84,\n\t\t\t\t\"label\": \"shanghai002\"\n\t\t\t}, {\n\t\t\t\t\"value\": 85,\n\t\t\t\t\"label\": \"shanghai003\"\n\t\t\t}, {\n\t\t\t\t\"value\": 86,\n\t\t\t\t\"label\": \"suqian001\"\n\t\t\t}],\n\t\t\t\"choices_apis\": [],\n\t\t\t\"method\": \"\",\n\t\t\t\"max_length\": 0,\n\t\t\t\"precision\": null,\n\t\t\t\"field\": \"ForeignKey\"\n\t\t}, {\n\t\t\t\"label\": \"\u5730\u533a\",\n\t\t\t\"help_text\": null,\n\t\t\t\"field_name\": \"region\",\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"PrimaryKeyRelatedField\",\n\t\t\t\"rules\": [{\n\t\t\t\t\"required\": true,\n\t\t\t\t\"message\": \"\u8be5\u5b57\u6bb5\u662f\u5fc5\u586b\u9879\u3002\"\n\t\t\t}],\n\t\t\t\"choices\": [{\n\t\t\t\t\"value\": 1,\n\t\t\t\t\"label\": \"\u4e0a\u6d77\u3010310000\u3011\"\n\t\t\t}, {\n\t\t\t\t\"value\": 21,\n\t\t\t\t\"label\": \"\u5bbf\u8fc1\u3010321300\u3011\"\n\t\t\t}, {\n\t\t\t\t\"value\": 34,\n\t\t\t\t\"label\": \"\u76d0\u57ce\u3010320900\u3011\"\n\t\t\t}],\n\t\t\t\"choices_apis\": [],\n\t\t\t\"method\": \"\",\n\t\t\t\"max_length\": 0,\n\t\t\t\"precision\": null,\n\t\t\t\"field\": \"ForeignKey\"\n\t\t}, {\n\t\t\t\"label\": \"\u534f\u4f5c\u4eba\",\n\t\t\t\"help_text\": null,\n\t\t\t\"field_name\": \"admins\",\n\t\t\t\"required\": false,\n\t\t\t\"type\": \"ManyRelatedField\",\n\t\t\t\"rules\": [],\n\t\t\t\"choices\": [{\n\t\t\t\t\"value\": 1,\n\t\t\t\t\"label\": \"hofeng\"\n\t\t\t}, {\n\t\t\t\t\"value\": 13,\n\t\t\t\t\"label\": \"18961330033\"\n\t\t\t}, {\n\t\t\t\t\"value\": 83,\n\t\t\t\t\"label\": \"shanghai001\"\n\t\t\t}, {\n\t\t\t\t\"value\": 84,\n\t\t\t\t\"label\": \"shanghai002\"\n\t\t\t}, {\n\t\t\t\t\"value\": 85,\n\t\t\t\t\"label\": \"shanghai003\"\n\t\t\t}, {\n\t\t\t\t\"value\": 86,\n\t\t\t\t\"label\": \"suqian001\"\n\t\t\t}],\n\t\t\t\"choices_apis\": [],\n\t\t\t\"method\": \"\",\n\t\t\t\"max_length\": 0,\n\t\t\t\"precision\": null,\n\t\t\t\"field\": \"ManyToManyField\"\n\t\t}, {\n\t\t\t\"label\": \"\u624b\u673a\u53f7\",\n\t\t\t\"help_text\": \"\u5ba2\u6e90\u624b\u673a\u53f7\",\n\t\t\t\"field_name\": \"mobile\",\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"CharField\",\n\t\t\t\"rules\": [{\n\t\t\t\t\"required\": true,\n\t\t\t\t\"message\": \"\u8be5\u5b57\u6bb5\u662f\u5fc5\u586b\u9879\u3002\"\n\t\t\t}],\n\t\t\t\"choices\": [],\n\t\t\t\"choices_apis\": [],\n\t\t\t\"method\": \"\",\n\t\t\t\"max_length\": 11,\n\t\t\t\"precision\": null,\n\t\t\t\"field\": \"CharField\"\n\t\t}, {\n\t\t\t\"label\": \"\u59d3\u540d\",\n\t\t\t\"help_text\": null,\n\t\t\t\"field_name\": \"name\",\n\t\t\t\"required\": false,\n\t\t\t\"type\": \"CharField\",\n\t\t\t\"rules\": [],\n\t\t\t\"choices\": [],\n\t\t\t\"choices_apis\": [],\n\t\t\t\"method\": \"\",\n\t\t\t\"max_length\": 32,\n\t\t\t\"precision\": null,\n\t\t\t\"field\": \"CharField\"\n\t\t}, {\n\t\t\t\"label\": \"\u65b0\u623f\u5ba2\u6e90\",\n\t\t\t\"help_text\": null,\n\t\t\t\"field_name\": \"new\",\n\t\t\t\"required\": false,\n\t\t\t\"type\": \"BooleanField\",\n\t\t\t\"rules\": [],\n\t\t\t\"choices\": [],\n\t\t\t\"choices_apis\": [],\n\t\t\t\"method\": \"\",\n\t\t\t\"max_length\": 0,\n\t\t\t\"precision\": null,\n\t\t\t\"field\": \"BooleanField\"\n\t\t}, {\n\t\t\t\"label\": \"\u4e8c\u624b\u623f\u5ba2\u6e90\",\n\t\t\t\"help_text\": null,\n\t\t\t\"field_name\": \"old\",\n\t\t\t\"required\": false,\n\t\t\t\"type\": \"BooleanField\",\n\t\t\t\"rules\": [],\n\t\t\t\"choices\": [],\n\t\t\t\"choices_apis\": [],\n\t\t\t\"method\": \"\",\n\t\t\t\"max_length\": 0,\n\t\t\t\"precision\": null,\n\t\t\t\"field\": \"BooleanField\"\n\t\t}, {\n\t\t\t\"label\": \"\u79df\u623f\u5ba2\u6e90\",\n\t\t\t\"help_text\": null,\n\t\t\t\"field_name\": \"rent\",\n\t\t\t\"required\": false,\n\t\t\t\"type\": \"BooleanField\",\n\t\t\t\"rules\": [],\n\t\t\t\"choices\": [],\n\t\t\t\"choices_apis\": [],\n\t\t\t\"method\": \"\",\n\t\t\t\"max_length\": 0,\n\t\t\t\"precision\": null,\n\t\t\t\"field\": \"BooleanField\"\n\t\t}, {\n\t\t\t\"label\": \"\u7b80\u8981\u8bf4\u660e\",\n\t\t\t\"help_text\": null,\n\t\t\t\"field_name\": \"desc\",\n\t\t\t\"required\": false,\n\t\t\t\"type\": \"CharField\",\n\t\t\t\"rules\": [],\n\t\t\t\"choices\": [],\n\t\t\t\"choices_apis\": [],\n\t\t\t\"method\": \"\",\n\t\t\t\"max_length\": 2000,\n\t\t\t\"precision\": null,\n\t\t\t\"field\": \"TextField\"\n\t\t}],\n\t\t\"tabs\": []\n\t},\n\t\"list\": [{\n\t\t\"label\": \"ID\",\n\t\t\"field_name\": \"id\",\n\t\t\"type\": \"IntegerField\",\n\t\t\"field\": \"AutoField\",\n\t\t\"width\": \"80\"\n\t}, {\n\t\t\"label\": \"\u624b\u673a\u53f7\",\n\t\t\"field_name\": \"mobile\",\n\t\t\"type\": \"CharField\",\n\t\t\"field\": \"CharField\"\n\t}, {\n\t\t\"label\": \"\u59d3\u540d\",\n\t\t\"field_name\": \"name\",\n\t\t\"type\": \"CharField\",\n\t\t\"field\": \"CharField\"\n\t}, {\n\t\t\"label\": \"\u4e3b\u7406\u4eba\",\n\t\t\"field_name\": \"master\",\n\t\t\"type\": \"StringRelatedField\",\n\t\t\"field\": \"ForeignKey\"\n\t}, {\n\t\t\"label\": \"\u65b0\u623f\u5ba2\u6e90\",\n\t\t\"field_name\": \"new\",\n\t\t\"type\": \"BooleanField\",\n\t\t\"field\": \"BooleanField\"\n\t}, {\n\t\t\"label\": \"\u4e8c\u624b\u623f\u5ba2\u6e90\",\n\t\t\"field_name\": \"old\",\n\t\t\"type\": \"BooleanField\",\n\t\t\"field\": \"BooleanField\"\n\t}, {\n\t\t\"label\": \"\u79df\u623f\u5ba2\u6e90\",\n\t\t\"field_name\": \"rent\",\n\t\t\"type\": \"BooleanField\",\n\t\t\"field\": \"BooleanField\"\n\t}, {\n\t\t\"label\": \"\u6dfb\u52a0\u65f6\u95f4\",\n\t\t\"field_name\": \"add_time\",\n\t\t\"type\": \"DateTimeField\",\n\t\t\"field\": \"DateTimeField\"\n\t}],\n\t\"read\": [{\n\t\t\"label\": \"\u4e3b\u7406\u4eba\",\n\t\t\"field_name\": \"master\",\n\t\t\"type\": \"StringRelatedField\"\n\t}, {\n\t\t\"label\": \"\u5730\u533a\",\n\t\t\"field_name\": \"region\",\n\t\t\"type\": \"StringRelatedField\"\n\t}, {\n\t\t\"label\": \"\u534f\u4f5c\u4eba\",\n\t\t\"field_name\": \"admins\",\n\t\t\"type\": \"ManyRelatedField\"\n\t}, {\n\t\t\"label\": \"\u6dfb\u52a0\u65f6\u95f4\",\n\t\t\"field_name\": \"add_time\",\n\t\t\"type\": \"DateTimeField\"\n\t}, {\n\t\t\"label\": \"\u624b\u673a\u53f7\",\n\t\t\"field_name\": \"mobile\",\n\t\t\"type\": \"CharField\"\n\t}, {\n\t\t\"label\": \"\u59d3\u540d\",\n\t\t\"field_name\": \"name\",\n\t\t\"type\": \"CharField\"\n\t}, {\n\t\t\"label\": \"\u65b0\u623f\u5ba2\u6e90\",\n\t\t\"field_name\": \"new\",\n\t\t\"type\": \"BooleanField\"\n\t}, {\n\t\t\"label\": \"\u4e8c\u624b\u623f\u5ba2\u6e90\",\n\t\t\"field_name\": \"old\",\n\t\t\"type\": \"BooleanField\"\n\t}, {\n\t\t\"label\": \"\u79df\u623f\u5ba2\u6e90\",\n\t\t\"field_name\": \"rent\",\n\t\t\"type\": \"BooleanField\"\n\t}, {\n\t\t\"label\": \"\u7b80\u8981\u8bf4\u660e\",\n\t\t\"field_name\": \"desc\",\n\t\t\"type\": \"CharField\"\n\t}],\n\t\"extra\": null\n}\n```\n\n\u4e0b\u9762\u662f\u5177\u4f53\u7684\u4f7f\u7528\u65b9\u6cd5\n\n### list_class\n\n```python\nclass CustomListSerializer(serializers.ModelSerializer):\n    master = serializers.StringRelatedField()\n    add_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')\n\n    class Meta:\n        model = Custom\n        fields = [\"id\", \"mobile\", \"name\", \"master\", \"new\", \"old\", \"rent\", \"add_time\"]\n        custom = {\n            \"id\": {'width': '80'}\n        }\n```\n\n\u8fd9\u662f\u4e00\u4e2a\u5178\u578b\u7684\u5217\u8868\u8bfb\u53d6\u7684\u5e8f\u5217\u5316\u5668\uff0c\u5143\u6570\u636e\u4e2d\u89c4\u5b9a\u7684\u8f93\u51fa\u5b57\u6bb5\uff0c\u65b0\u589e\u7684custom\u5b57\u5178\u8868\u660e\u67d0\u4e2a\u5b57\u6bb5\u7684\u7279\u522b\u7ea6\u5b9a\u3002\n\n\u5b57\u5178\u7684\u5065\u540d\u7528\u5b57\u6bb5\u540d\u8868\u793a\u5b9a\u4e49\u67d0\u4e2a\u5b57\u6bb5\uff1b\n\nvalue\u503c\u662f\u4e00\u4e2a\u5b57\u5178\uff0c\u5065\u540d\u81ea\u5df1\u5b9a\u4e49\uff0c\u53cd\u9988\u5230\u524d\u7aef\u540e\uff0c\u524d\u7aef\u65b9\u4fbf\u8fdb\u884c\u89e3\u6790\u3002\n\n\u5efa\u8bae\u4fdd\u7559width\uff0clabel\u8fd9\u7c7b\u5b57\u6bb5\uff0c\u603b\u4e4b\uff0c\u8fd9\u91cc\u5b9a\u4e49\u4ec0\u4e48\uff0c\u524d\u7aef\u5c31\u4f1a\u6536\u5230\u4ec0\u4e48\uff0c\u7136\u540e\u524d\u7aef\u8fdb\u884c\u6e32\u67d3\u3002\n\n\u8f93\u51fa\u5230\u524d\u7aef\u540e\uff0c\u5bf9\u5e94\u53c2\u6570\u5065\u540d\u4e3a\uff1alist\n\n### filter_class\n\n\u4f5c\u4e3a\u7b5b\u9009\u5668\uff0c\u8981\u5b9a\u4e49\u6bcf\u4e2a\u7b5b\u9009\u9879\uff0c\u8fd9\u662f\u6ca1\u529e\u6cd5\u907f\u514d\u7684\uff0c\u4f8b\u5982\uff1a\n\n```python\nclass CustomFilter(django_filters.rest_framework.FilterSet):\n    mobile = django_filters.CharFilter(method='keyword_filter', help_text=\"\u624b\u673a\u53f7\")\n    name = django_filters.CharFilter(method='keyword_filter', help_text=\"\u59d3\u540d\")\n    desc = django_filters.CharFilter(method='keyword_filter', help_text=\"\u8bf4\u660e\")\n    new = django_filters.BooleanFilter(method='common_filter', help_text=\"\u65b0\u623f\u5ba2\u6e90\", label={'options': get_easy_bool()})\n    old = django_filters.BooleanFilter(method='common_filter', help_text=\"\u4e8c\u624b\u623f\u5ba2\u6e90\", label={'options': get_easy_bool()})\n    rent = django_filters.BooleanFilter(method='common_filter', help_text=\"\u79df\u623f\u5ba2\u6e90\", label={'options': get_easy_bool()})\n```\n\n\u4ee5\u4e0a\u5c31\u662f\u5bf9\u7b5b\u9009\u5668\u7684\u5b9a\u4e49\uff0c\u5bf9\u9879\u7684\u5b9a\u4e49\uff0c\u653e\u5728label\u8fdb\u884c\u5b9a\u4e49\uff0c\u9009\u62e9\u7c7b\u7684\u7ed9options\u503c\uff0chelp_text\u662f\u663e\u793a\u51fa\u6765\u7684\u540d\u79f0\n\n\u8f93\u51fa\u5230\u524d\u7aef\u540e\uff0c\u5bf9\u5e94\u53c2\u6570\u5065\u540d\u4e3a\uff1afilter\n\n### create_class\n\n\u521b\u5efa\u7c7b\u7684\u8f93\u51fa\uff0c\u662f\u4e3a\u4e86\u524d\u7aef\u81ea\u52a8\u6784\u9020\u63d0\u4ea4\u8868\u5355\u800c\u5b9a\uff0c\u5e8f\u5217\u5316\u5668\u5199\u6cd5\u6ca1\u6709\u7279\u522b\uff0c\u548clist\u4e00\u6837\uff0c\u53ef\u4ee5\u5728\u5143\u6570\u636e\u4e2d\u589e\u52a0\u4e00\u4e2acustom\u5b57\u5178\uff0c\u5bf9\u5e94\u628a\u6bcf\u4e2a\u5b57\u6bb5\u7684\u7279\u522b\u8981\u6c42\u8f93\u9001\u5230\u524d\u7aef\u3002\n\n\u548c\u5176\u4ed6\u4e0d\u540c\u7684\u662f\uff0ccreate\u7684Meta\u4e0b\u53ef\u4ee5\u989d\u5916\u589e\u52a0\u4e00\u4e2atabs\uff0c\u7ed3\u6784\u4e3a\uff1a\n\n```python\ntabs = [{\n    'label': '\u57fa\u672c\u4fe1\u606f',\n    'fields': ['mobile', 'name', 'region', 'desc']\n}, {\n    'label': '\u6743\u9650\u914d\u7f6e',\n    'fields': ['master', 'admins', 'new', 'old', 'rent']\n}]\n```\n\n\u53e6\u5916\uff0c\u8fd8\u589e\u52a0\u4e86\u4e00\u4e2ainlines\u7684\u6570\u636e\uff0c\u7ed3\u6784\u5982\u4e0b\n\n```python\ninlines = {\n    'custom': {\n        'class': TrackCreateSerializer,\n        'api': '/admin/user/track/data/',\n        'limit': 10\n    }\n}\n```\n\u8bf4\u660e\uff1a\u5065\u540d\u662f\u4f5c\u4e3a\u4e3b\u952e\u7684\u5b57\u6bb5\u540d\uff0c\u4e5f\u5c31\u662f\u5176\u4ed6\u5b50\u6570\u636e\u7684\u4e3b\u5b57\u6bb5\u540d\uff1bclass\u662f\u8fd9\u4e2a\u5b50\u6570\u636e\u521b\u5efa\u7684\u5e8f\u5217\u5316\u5668\uff1bapi\u662f\u521b\u5efa\u63a5\u53e3\uff1blimit\u662f\u4e00\u6b21\u6700\u591a\u591a\u5c11\u4e2a\n\n\u8fd9\u6837\u8bbe\u5b9a\uff0c\u524d\u7aef\u5c31\u53ef\u4ee5\u5f97\u5230\u8fd9\u4e2atabs\uff0c\u53ef\u4ee5\u7528\u4e8e\u6dfb\u52a0\u8868\u5355\u5206\u6b65\u6267\u884c\u3002\n\n\u8f93\u51fa\u5230\u524d\u7aef\u540e\uff0c\u5bf9\u5e94\u53c2\u6570\u5065\u540d\u4e3a\uff1acreate\n\n### read_class\n\n\u8bfb\u53d6\u8be6\u7ec6\u5185\u5bb9\u7684\u5e8f\u5217\u5316\u5668\uff0c\u8981\u6ce8\u610f\u7684\u662f\u6700\u597d\u4e0d\u8981\u6784\u5efa\u5916\u952e\u5bf9\u8c61\uff0c\u800c\u662f\u8981\u7528serializers.StringRelatedField()\u65b9\u6cd5\u628a\u5916\u952e\u8fdb\u884c\u6587\u672c\u5316\uff0c\u8fd9\u6837\u624d\u80fd\u5728\u524d\u7aef\u6b63\u5e38\u663e\u793a\u3002\n\n\u8f93\u51fa\u5230\u524d\u7aef\u540e\uff0c\u5bf9\u5e94\u53c2\u6570\u5065\u540d\u4e3a\uff1aread\n\n### extra\n\n\u8fd9\u4e2a\u7528\u4e8e\u989d\u5916\u7ed9\u524d\u7aef\u4e00\u4e2a\u6269\u5c55\u7684\u6570\u636e\u5b57\u6bb5\uff0c\u53ef\u4ee5\u8bbe\u5b9a\u4e00\u5207\u80fd\u591f\u8f6c\u4e3ajson\u7684\u6570\u636e\uff0c\u7528\u4e8e\u81ea\u5df1\u5b9a\u4e49\u4e0e\u524d\u7aef\u7684\u534f\u8bae\n\n\u8f93\u5165\u5230\u524d\u7aef\u540e\uff0c\u5bf9\u5e94\u53c2\u6570\u5065\u540d\u4e3a\uff1aextra\n\n# \u7248\u672c\u5386\u53f2\n\n1.0.5 \u4fee\u590d\u5916\u952e\u9009\u62e9\u9879\u8fc7\u591a\u7684\u95ee\u9898\uff0c\u6dfb\u52a0choices_limit\u53c2\u6570\uff0c\u9ed8\u8ba4\u8d85\u8fc730\u4e2a\u9009\u9879\u5c31\u4e0d\u5728\u4ecechoices\u91cc\u81ea\u52a8\u53d6\u9009\u62e9\u9879\uff0c\u8bf7\u5728custom\u91cc\u5bf9\u5b57\u6bb5\u68c0\u7d22\u65b9\u5f0f\u8fdb\u884c\u914d\u7f6e\n\n1.0.6 \u5bf9\u9690\u85cf\u5b57\u6bb5\u652f\u6301\u5c4f\u853d\uff0c\u540c\u65f6\u4fee\u590d\u4e86\u4e00\u4e0b\u53ef\u80fd\u51fa\u73b0\u7684bug\uff1b\u589e\u52a0\u4e86\u6570\u5b57\u5b57\u6bb5\u7684\u5c0f\u6570\u70b9\u957f\u5ea6\u5224\u65ad\n\n1.0.7 \u589e\u52a0inline\u6a21\u5f0f\u7684\u914d\u7f6e\u6570\u636e\u8f93\u51fa\uff0c\u89c4\u5219\u89c1create_class\u8bf4\u660e\n\n1.0.8 \u4f18\u5316\u4e86\u4ee3\u7801\uff0c\u805a\u7c7b\u4e86\u51fd\u6570\uff1b\u589e\u52a0list\u548cread\u65b9\u5f0f\u4e0b\u7684\u53c2\u6570\uff0c\u4e3apatch\u5b57\u6bb5\u7ea7\u63d0\u4f9b\u65b9\u4fbf\n\n1.0.9 \u4fee\u6b63inlines\u7684bug\n\n1.0.10 \u4fee\u6b63create\u7684bug\n\n1.0.11 \u589e\u52a0default\u503c\u7684\u8f93\u51fa\n\n1.0.12 \u4fee\u590dbug\n\n1.1.0  \u589e\u52a0update\n\n1.1.1  \u4fee\u6539\u9ed8\u8ba4tabs\n\n1.1.2  \u4fee\u590dbug\n\n1.1.3  \u4fee\u590dbug\n\n1.1.4  inlines\u5185\u589e\u52a0filter\u53c2\u6570\n\n1.2.0 \u65b0\u589e\u5de5\u5177\u5305\uff0c\u8be6\u89c1hadmin.utils\n\n1.2.1 \u4fee\u590dlist\u65b9\u6cd5\u4e0a\u7684bug\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "\u9488\u5bf9\u81ea\u52a8\u5316\u7ed9\u4e88\u524d\u7aef\u914d\u7f6e\u6587\u4ef6\u7684DRF\u5c01\u88c5",
    "version": "1.2.1",
    "project_urls": {
        "Homepage": "https://github.com/spirits001/python-HAdmin"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f6e916b95825046bffec48cb7a36a699e3a604b232180f14183dd49c170cfad4",
                "md5": "d28a554cf14202177428bec7f30abd21",
                "sha256": "3c7f6cd90865f4e84fee46c9eb8a2f0073770c571492fb21dc044fd192b130b7"
            },
            "downloads": -1,
            "filename": "hadmin-1.2.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d28a554cf14202177428bec7f30abd21",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3",
            "size": 10740,
            "upload_time": "2024-01-30T11:19:26",
            "upload_time_iso_8601": "2024-01-30T11:19:26.360541Z",
            "url": "https://files.pythonhosted.org/packages/f6/e9/16b95825046bffec48cb7a36a699e3a604b232180f14183dd49c170cfad4/hadmin-1.2.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fc61dd7ecb42f3c27b25ee67b115b62944a038f3f1d741a2303c2cd87d6243fc",
                "md5": "db6b35ae7039e2be003d11d4c9c4ff7c",
                "sha256": "94973b3c98d1b744325640259d1489ac726c68eab02b4dfb87f612324d585b06"
            },
            "downloads": -1,
            "filename": "hadmin-1.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "db6b35ae7039e2be003d11d4c9c4ff7c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3",
            "size": 14034,
            "upload_time": "2024-01-30T11:19:35",
            "upload_time_iso_8601": "2024-01-30T11:19:35.517457Z",
            "url": "https://files.pythonhosted.org/packages/fc/61/dd7ecb42f3c27b25ee67b115b62944a038f3f1d741a2303c2cd87d6243fc/hadmin-1.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-30 11:19:35",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "spirits001",
    "github_project": "python-HAdmin",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "hadmin"
}
        
Elapsed time: 0.18831s