# django-power-admin
Django提供了快捷的生成后台管理站点的能力。本应用旨在增强Django Admin的能力,提供丰富的Admin、Widget、ListFilter、Form等等界面扩展类,同时也为常用的数据管理模型提供完整的管理功能。
## 使用说明
1. 依赖`django-middleware-global-request`,请参考[django-middleware-global-request文档](https://pypi.org/project/django-middleware-global-request/)。
1. 依赖`django_static_fontawesome`,请参考[django_static_fontawesome文档](https://pypi.org/project/django-static-fontawesome/)。
1. 依赖`django_static_jquery_ui`,请参考[django_static_jquery_ui文档](https://pypi.org/project/django-static-jquery-ui/)。
1. 推荐使用`django-app-requires`解决包依赖问题,请参考[django-app-requires文档](https://pypi.org/project/django-app-requires/)。
## 功能扩展清单
### Admin后台管理界面整体控制
| 主要功能 |
| -------- |
| `@todo` 定制化的登录界面 |
| `@todo` 登录框增加图形验证码 |
| `@todo` 登录后增加短信验证 |
| `@todo` 顶部导航 |
| `@todo` 左侧导航 |
| `@todo` 首页控制面板 |
| `@todo` 应用模块级控制面板 |
| `@todo` 用户中心子站 |
| `@todo` 中国风的组织架构管理和用户管理 |
### PowerAdmin核心功能
| 类名 | 主要功能 |
| ---- | -------- |
| ChangelistToolbar机制 | 提供列表页顶部按钮自定义功能 |
| ChangelistObjectToolbar机制 | 提供列表页行按钮自定义功能 |
| Extra View机制 | 提供添加额外视图函数的功能 |
| View Hook机制 | 提供pre_xxx_view,post_xxx_view的Hook机制,<br />方便用户在进入视图前执行准备或清除工作 |
| Extra Context机制 | 为视图渲染注入额外的模板context机制。<br />`ChangelistToolbar机制`就是通过本机制注入额外的按钮列表数据的。 |
| Read & Change机制 | 设置只读、编辑两个不同的入口。这样现符合用户的操作习惯。 |
| Simple Export机制 | 数据导出机制,<br />默认即可导出所有表字段,<br />同时支持EXCEL模板配置、表头控制、字段配置等等。 |
| [排序记录上下移动机制](#django_power_admin.admin.PowerAdmin排序记录上下移动机制) | 每行记录上有上移&下移按钮,<br />通过点击上下移动按钮调整记录的排序。|
| [ListFilter Media机制](#django_power_admin.widgets.TextInputFieldFilter实现原理) | 允许自定义的ListFilter类,<br />通过添加`class Media:`来引入额外的js/css文件。 |
### Admin辅助函数
| 函数名 | 主要功能 |
| ---- | -------- |
| add_extra_css | 为当前页添加额外的css代码段 |
| add_extra_js | 为当前页添加额外的js代码段 |
### Widget扩展类
| 类名 | 主要功能 |
| ---- | -------- |
| [Select2](#django_power_admin.widgets.Select2) | 将标准select下拉框转为select2样式下拉框 |
| SelectMultiple2 | 将标准select复选框转为select2样式下拉式复选框 |
| [ConfigTable](#django_power_admin.widgets.ConfigTable) | 健值对配置项编辑控件<br />数据json序列化后保存在TextField中 |
| PopupConfigTable | 弹出式健值对配置项编辑控件<br />数据json序列化后保存在TextField中 |
| [AllUsersSelect](#django_power_admin.widgets.AllUsersSelect) | 用户选择控件,使用Select2实现<br />提供用户信息模糊搜索功能<br />不需要用户模块管理权限 |
| `@todo` PasswordResetableWidget | 密码重置字段(只重置,不显示)|
### Field扩展类
| 类名 | 主要功能 |
| ---- | -------- |
| MPTTModelChoiceField | MPTT数据模型中的Parent字段关联的表单字段,<br />使用Select2样式控件。<br />建议在MPTTAdminForm中使用 |
| ModelChoiceFieldWithLabelProperty | 标准ModelChoiceField的扩展,<br />支持使用自定义的标签函数 |
### Form扩展类
### ListFilter扩展类
| 类名 | 主要功能 |
| --- | ----- |
| [TextInputFieldFilter](#django_power_admin.filters.TextInputFieldFilter) | 使用文本框的过滤条件。 |
| [DateRangeFilter](#django_power_admin.filters.DateRangeFilter) | 日期区间过滤条件。 |
## 使用方法说明
### django_power_admin的引入
*pro/settings.py*
```
INSTALLED_APPS = [
...
'django_middleware_global_request',
'django_static_fontawesome',
'django_static_jquery_ui',
'django_simple_tags',
'django_power_admin',
...
]
MIDDLEWARE = [
...
'django_middleware_global_request.middleware.GlobalRequestMiddleware',
...
]
```
### <a name="django_power_admin.admin.PowerAdmin排序记录上下移动机制"></a>django_power_admin.admin.PowerAdmin排序记录上下移动机制
#### django_power_admin.admin.PowerAdmin排序记录上下移动机制效果图
![django_power_admin.admin.PowerAdmin排序支持效果预览图](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/admin/django_power_admin_admin_sorting_preview.png)
#### django_power_admin.admin.PowerAdmin排序记录上下移动机制使用方法
*models.py*
```
class SortableAdminExmapleModel(models.Model):
title = models.CharField(max_length=64, verbose_name="Title")
display_order = models.IntegerField(null=True, blank=True, verbose_name="Display Order")
class Meta:
verbose_name = "排序演示"
verbose_name_plural = "排序演示"
def __str__(self):
return str(self.pk)
```
*admin.py*
```
from django.contrib import admin
from django_power_admin.admin import PowerAdmin
from .models import SortableAdminExmapleModel
class SortableAdminExmapleModelAdmin(PowerAdmin):
list_display = ["title"]
ordering = ["display_order"]
changelist_object_toolbar_buttons = [
"django_power_admin_move_up",
"django_power_admin_move_down",
"read_button",
"change_button",
"delete_button",
]
admin.site.register(SortableAdminExmapleModel, SortableAdminExmapleModelAdmin)
```
### <a name="django_power_admin.widgets.Select2"></a>django_power_admin.widgets.Select2
#### django_power_admin.widgets.Select2效果预览图
![django_power_admin.widgets.Select2效果预览图](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/widgets/Select2/django_power_admin_widgets_select2_preview.png)
#### django_power_admin.widgets.Select2使用方法
*models.py*
```
from django.db import models
class Select2ExampleCategory(models.Model):
name = models.CharField(max_length=64, verbose_name="Name")
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
def __str__(self):
return self.name
class Select2ExampleModel(models.Model):
title = models.CharField(max_length=64, verbose_name="Title")
category = models.ForeignKey(Select2ExampleCategory, on_delete=models.CASCADE, verbose_name="Category")
class Meta:
verbose_name = "可搜索下拉框演示"
verbose_name_plural = "可搜索下拉框演示"
def __str__(self):
return self.title
```
*admin.py*
```
from django import forms
from django.contrib import admin
from django_power_admin.widgets import Select2
from .models import Select2ExampleCategory
from .models import Select2ExampleModel
class Select2ExampleCategoryAdmin(admin.ModelAdmin):
list_display = ["name"]
class Select2ExampleModelForm(forms.ModelForm):
class Meta:
widgets = {
"category": Select2(),
}
class Select2ExampleModelAdmin(admin.ModelAdmin):
form = Select2ExampleModelForm
list_display = ["title"]
admin.site.register(Select2ExampleCategory, Select2ExampleCategoryAdmin)
admin.site.register(Select2ExampleModel, Select2ExampleModelAdmin)
```
### <a name="django_power_admin.widgets.ConfigTable"></a>django_power_admin.widgets.ConfigTable
#### django_power_admin.widgets.ConfigTable效果预览图
![django_power_admin.widgets.ConfigTable效果预览图](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/widgets/ConfigTable/django_power_admin_widgets_config_table_preview.png)
#### django_power_admin.widgets.ConfigTable使用方法
*models.py*
```
from django.db import models
class ConfigTableExampleModel(models.Model):
config = models.TextField(null=True, blank=True, verbose_name="配置")
class Meta:
verbose_name = "配置表控件演示"
verbose_name_plural = "配置表控件演示"
def __str__(self):
return str(self.pk)
```
*admin.py*
```
from django import forms
from django.contrib import admin
from django_power_admin.widgets import ConfigTable
class ConfigTableExampleModelForm(forms.ModelForm):
class Meta:
widgets = {
"config": ConfigTable(),
}
class ConfigTableExampleModelAdmin(admin.ModelAdmin):
form = ConfigTableExampleModelForm
admin.site.register(ConfigTableExampleModel, ConfigTableExampleModelAdmin)
```
### <a name="django_power_admin.widgets.AllUsersSelect"></a>django_power_admin.widgets.AllUsersSelect
#### django_power_admin.widgets.AllUsersSelect预览效果
![django_power_admin.widgets.AllUsersSelect效果预览图](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/widgets/AllUsersSelect/AllUsersSelect.png)
#### django_power_admin.widgets.AllUsersSelect使用方法
*models.py*
```
from django.db import models
class Project(models.Model):
owner = models.ForeignKey(global_settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name="+", verbose_name=_("Owner"))
class Meta:
verbose_name = "Project"
verbose_name_plural = "Projects"
def __str__(self):
return str(self.pk)
```
*admin.py*
```
from django import forms
from django.contrib import admin
from django_power_admin.widgets import AllUsersSelect
from .models import Project
class ProjectForm(forms.ModelForm):
class Meta:
widgets = {
"owner": AllUsersSelect(),
}
class ProjectAdmin(admin.ModelAdmin):
form = ProjectForm
admin.site.register(Project, ProjectAdmin)
```
### <a name="django_power_admin.filters.TextInputFieldFilter"></a>django_power_admin.widgets.TextInputFieldFilter
#### django_power_admin.filters.TextInputFieldFilter预览效果
![django_power_admin.filters.TextInputFieldFilter预览效果](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/filters/TextInputFieldFilter/TextInputFieldFilter.png)
#### django_power_admin.filters.TextInputFieldFilter使用方法
```
from django.contrib import admin
from django_power_admin.filters import TextInputFieldFilter
class ExampleAdmin(admin.ModelAdmin):
list_filter = [
("title", TextInputFieldFilter),
"description",
"enable",
]
list_display = ["title", "description", "enable"]
```
#### <a name="django_power_admin.filters.TextInputFieldFilter实现原理"></a>django_power_admin.filters.TextInputFieldFilter实现原理
使用了django_power_admin引入的ListFilter Media机制,
通过在类内部定义`class Media`,
导入ListFilter需要使用到的js/css文件,
导入的js文件,可以按django标准media文件引入机制进行自动化的去重和依赖排序。
```
from django.contrib.admin import FieldListFilter
class TextInputFieldFilter(FieldListFilter):
template = 'django_power_admin/filters/TextInputFieldFilter.html'
...
class Media:
css = {
"all": [
"django_power_admin/filters/TextInputFieldFilter/css/TextInputFieldFilter.css",
]
}
js = [
"django_power_admin/assets/js/parseParam.js",
"admin/js/vendor/jquery/jquery.js",
"django_power_admin/filters/TextInputFieldFilter/js/TextInputFieldFilter.js",
"admin/js/jquery.init.js",
]
```
### <a name="django_power_admin.filters.DateRangeFilter"></a>django_power_admin.filters.DateRangeFilter
#### django_power_admin.filters.DateRangeFilter效果预览
![django_power_admin.filters.DateRangeFilter](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/filters/DateRangeFilter/DateRangeFilter.png)
#### django_power_admin.filters.DateRangeFilter使用方式
```
from django.contrib import admin
from django_power_admin.filters import DateRangeFilter
class ExampleAdmin(admin.ModelAdmin):
list_filter = [
"username",
("date_join", DateRangeFilter),
"is_active",
]
list_display = ["username", "date_join", "is_active"]
```
### Admin样式类
- inline-narror-input
TabularInline字符串输入框改为小框。
*使用范围:*
- 可加在TabularInline类的claases属性中。
- related-actions-hidden
隐藏外键的增改删按钮。
*使用范围:*
- 可加在fieldsets的classes属性中。
- 可以加在TabularInline类的claases属性中。
- inline-original-hidden
隐藏TabularInline及StackInline中的orininal显示。
*使用范围:*
- 可加在TabularInline类的claases属性中。
- 可加在StackInline类的claases属性中。
- form-row-c2
FormChange表单两例显示,同时控制textarea的宽度。
*使用范围:*
- 可加在fieldsets的classes属性中。
### Admin全局控制
- DJANGO_ADMIN_USE_FIXED_WIDTH_LAYOUT
当DJANGO_ADMIN_USE_FIXED_WIDTH_LAYOUT=True,Admin管理后台设置为固定宽度,且居中显示。可通过以下设置控制宽度及背景色。
*关联设置项:*
- DJANGO_ADMIN_USE_FIXED_WIDTH_LAYOUT = False
- DJANGO_ADMIN_WIDTH = 1280px
- DJANGO_ADMIN_BACKGROUND_COLOR = "#f5f6f8"
- DJANGO_ADMIN_FOOTER_COLOR = "#c5cbd2"
## 版本记录
### v0.1.7
- 项目启动。
- 框架搭建。
- PowerAdmin类基本完成。
### v0.1.10
- get_extra_views更名为get_extra_view_urls,避免与其它方法名冲突。
- view_action更名为read_xxx。xxx_action更名为xxx_button。
- 在list_display中追加change_list_object_toolbar字段。
### v0.1.12
- 增加has_change_permission_real, has_delete_permission_real方法,解决read/change机制导致的原始权限判断丢失的情况。
- 增加get_messages方法, 用于获取站点当前的messages队列。
- 增加get_power_admin_class,用于统一扩展所有PowerAdmin的子类。
### v0.1.18
- 修正get_changelist_object_row_classes_javascript方法在遇到其它错误时导致的异常行为。
- ChangelistObjectToolbarButton可以直接引用extra view(需要为extra view添加按钮额外属性,如:short_description、icon、classes等)。
- change_list_xxx更名为changelist_xxx(注意:可能引起新旧版本的不兼容,特别是子类配置的change_list_toolbar_buttons属性需要改名为changelist_toolbar_buttons)。
- 引入ChangelistToolbar机制,用于添加额外的列表页顶部按钮。
### v0.1.20
- 添加简易数据分享机制的支持(simple share model)。
- 添加数据导出功能。
### v0.1.21
- 添加适用于TextField使用的“键值对”控件。
- PowerAdmin中方法名加上django_power_admin_前缀,避免与其它扩展类冲突。
### v0.1.23
- 修正Select2、SelectMultiple2、ConfigTable在inline表单中的使用问题。
- 新增django_power_admin.widgets.AllUsersSelect。
### v0.1.24
- 新增django_power_admin.filters.TextInputFieldFilter。
- 新增list_filter类通过定义内部的`Media:`引入额外的js/css文件的机制。
### v0.1.25
- 新增django_power_admin.filters.DateRangeFilter。
### v0.1.27
- 修正ChangelistObjectToolbar按钮换行的问题。
### v0.1.29
- 兼容django 4.x。
- 兼容python 2.7。
- 修正排序Admin未设置ordering时的异常。
### v0.1.30
- 修正get_ordering强制添加display_order字段导致的问题。
### v0.1.31
- 修正ChangelistObjectToolBarButton的默认target=self问题,修正后的默认target=_self。
- 使用zenutils依赖包以简化不必要的依赖关系。
### v0.1.35
- 修正DateRangeFilter结束日期框搜索条件名称错误的问题。
### v0.1.36
- 增加站点固定宽度居中。
- 增加Admin样式类:form-row-c2、inline-original-hidden、related-actions-hidden、inline-narror-input。
- 增加PopupConfigTable控件。
### v0.1.37
- 文档更新。
Raw data
{
"_id": null,
"home_page": "",
"name": "django-power-admin",
"maintainer": "He LianJia",
"docs_url": null,
"requires_python": "",
"maintainer_email": "helianjia@zencore.cn",
"keywords": "django,django admin,django power admin,django admin extensions",
"author": "He LianJia",
"author_email": "helianjia@zencore.cn",
"download_url": "https://files.pythonhosted.org/packages/ca/5b/18440bf9b0a538d109be7e4db1188e999f5b3db4668d0822a1f2eba99073/django-power-admin-0.1.37.tar.gz",
"platform": null,
"description": "# django-power-admin\n\nDjango\u63d0\u4f9b\u4e86\u5feb\u6377\u7684\u751f\u6210\u540e\u53f0\u7ba1\u7406\u7ad9\u70b9\u7684\u80fd\u529b\u3002\u672c\u5e94\u7528\u65e8\u5728\u589e\u5f3aDjango Admin\u7684\u80fd\u529b\uff0c\u63d0\u4f9b\u4e30\u5bcc\u7684Admin\u3001Widget\u3001ListFilter\u3001Form\u7b49\u7b49\u754c\u9762\u6269\u5c55\u7c7b\uff0c\u540c\u65f6\u4e5f\u4e3a\u5e38\u7528\u7684\u6570\u636e\u7ba1\u7406\u6a21\u578b\u63d0\u4f9b\u5b8c\u6574\u7684\u7ba1\u7406\u529f\u80fd\u3002\n\n## \u4f7f\u7528\u8bf4\u660e\n\n1. \u4f9d\u8d56`django-middleware-global-request`\uff0c\u8bf7\u53c2\u8003[django-middleware-global-request\u6587\u6863](https://pypi.org/project/django-middleware-global-request/)\u3002\n1. \u4f9d\u8d56`django_static_fontawesome`\uff0c\u8bf7\u53c2\u8003[django_static_fontawesome\u6587\u6863](https://pypi.org/project/django-static-fontawesome/)\u3002\n1. \u4f9d\u8d56`django_static_jquery_ui`\uff0c\u8bf7\u53c2\u8003[django_static_jquery_ui\u6587\u6863](https://pypi.org/project/django-static-jquery-ui/)\u3002\n1. \u63a8\u8350\u4f7f\u7528`django-app-requires`\u89e3\u51b3\u5305\u4f9d\u8d56\u95ee\u9898\uff0c\u8bf7\u53c2\u8003[django-app-requires\u6587\u6863](https://pypi.org/project/django-app-requires/)\u3002\n\n## \u529f\u80fd\u6269\u5c55\u6e05\u5355\n\n### Admin\u540e\u53f0\u7ba1\u7406\u754c\u9762\u6574\u4f53\u63a7\u5236\n\n| \u4e3b\u8981\u529f\u80fd |\n| -------- |\n| `@todo` \u5b9a\u5236\u5316\u7684\u767b\u5f55\u754c\u9762 |\n| `@todo` \u767b\u5f55\u6846\u589e\u52a0\u56fe\u5f62\u9a8c\u8bc1\u7801 |\n| `@todo` \u767b\u5f55\u540e\u589e\u52a0\u77ed\u4fe1\u9a8c\u8bc1 |\n| `@todo` \u9876\u90e8\u5bfc\u822a |\n| `@todo` \u5de6\u4fa7\u5bfc\u822a |\n| `@todo` \u9996\u9875\u63a7\u5236\u9762\u677f |\n| `@todo` \u5e94\u7528\u6a21\u5757\u7ea7\u63a7\u5236\u9762\u677f |\n| `@todo` \u7528\u6237\u4e2d\u5fc3\u5b50\u7ad9 |\n| `@todo` \u4e2d\u56fd\u98ce\u7684\u7ec4\u7ec7\u67b6\u6784\u7ba1\u7406\u548c\u7528\u6237\u7ba1\u7406 |\n\n### PowerAdmin\u6838\u5fc3\u529f\u80fd\n\n| \u7c7b\u540d | \u4e3b\u8981\u529f\u80fd |\n| ---- | -------- |\n| ChangelistToolbar\u673a\u5236 | \u63d0\u4f9b\u5217\u8868\u9875\u9876\u90e8\u6309\u94ae\u81ea\u5b9a\u4e49\u529f\u80fd |\n| ChangelistObjectToolbar\u673a\u5236 | \u63d0\u4f9b\u5217\u8868\u9875\u884c\u6309\u94ae\u81ea\u5b9a\u4e49\u529f\u80fd |\n| Extra View\u673a\u5236 | \u63d0\u4f9b\u6dfb\u52a0\u989d\u5916\u89c6\u56fe\u51fd\u6570\u7684\u529f\u80fd |\n| View Hook\u673a\u5236 | \u63d0\u4f9bpre_xxx_view\uff0cpost_xxx_view\u7684Hook\u673a\u5236\uff0c<br />\u65b9\u4fbf\u7528\u6237\u5728\u8fdb\u5165\u89c6\u56fe\u524d\u6267\u884c\u51c6\u5907\u6216\u6e05\u9664\u5de5\u4f5c |\n| Extra Context\u673a\u5236 | \u4e3a\u89c6\u56fe\u6e32\u67d3\u6ce8\u5165\u989d\u5916\u7684\u6a21\u677fcontext\u673a\u5236\u3002<br />`ChangelistToolbar\u673a\u5236`\u5c31\u662f\u901a\u8fc7\u672c\u673a\u5236\u6ce8\u5165\u989d\u5916\u7684\u6309\u94ae\u5217\u8868\u6570\u636e\u7684\u3002 |\n| Read & Change\u673a\u5236 | \u8bbe\u7f6e\u53ea\u8bfb\u3001\u7f16\u8f91\u4e24\u4e2a\u4e0d\u540c\u7684\u5165\u53e3\u3002\u8fd9\u6837\u73b0\u7b26\u5408\u7528\u6237\u7684\u64cd\u4f5c\u4e60\u60ef\u3002 |\n| Simple Export\u673a\u5236 | \u6570\u636e\u5bfc\u51fa\u673a\u5236\uff0c<br />\u9ed8\u8ba4\u5373\u53ef\u5bfc\u51fa\u6240\u6709\u8868\u5b57\u6bb5\uff0c<br />\u540c\u65f6\u652f\u6301EXCEL\u6a21\u677f\u914d\u7f6e\u3001\u8868\u5934\u63a7\u5236\u3001\u5b57\u6bb5\u914d\u7f6e\u7b49\u7b49\u3002 |\n| [\u6392\u5e8f\u8bb0\u5f55\u4e0a\u4e0b\u79fb\u52a8\u673a\u5236](#django_power_admin.admin.PowerAdmin\u6392\u5e8f\u8bb0\u5f55\u4e0a\u4e0b\u79fb\u52a8\u673a\u5236) | \u6bcf\u884c\u8bb0\u5f55\u4e0a\u6709\u4e0a\u79fb&\u4e0b\u79fb\u6309\u94ae\uff0c<br />\u901a\u8fc7\u70b9\u51fb\u4e0a\u4e0b\u79fb\u52a8\u6309\u94ae\u8c03\u6574\u8bb0\u5f55\u7684\u6392\u5e8f\u3002|\n| [ListFilter Media\u673a\u5236](#django_power_admin.widgets.TextInputFieldFilter\u5b9e\u73b0\u539f\u7406) | \u5141\u8bb8\u81ea\u5b9a\u4e49\u7684ListFilter\u7c7b\uff0c<br />\u901a\u8fc7\u6dfb\u52a0`class Media:`\u6765\u5f15\u5165\u989d\u5916\u7684js/css\u6587\u4ef6\u3002 |\n\n### Admin\u8f85\u52a9\u51fd\u6570\n| \u51fd\u6570\u540d | \u4e3b\u8981\u529f\u80fd |\n| ---- | -------- |\n| add_extra_css | \u4e3a\u5f53\u524d\u9875\u6dfb\u52a0\u989d\u5916\u7684css\u4ee3\u7801\u6bb5 |\n| add_extra_js | \u4e3a\u5f53\u524d\u9875\u6dfb\u52a0\u989d\u5916\u7684js\u4ee3\u7801\u6bb5 |\n\n\n### Widget\u6269\u5c55\u7c7b\n\n| \u7c7b\u540d | \u4e3b\u8981\u529f\u80fd |\n| ---- | -------- |\n| [Select2](#django_power_admin.widgets.Select2) | \u5c06\u6807\u51c6select\u4e0b\u62c9\u6846\u8f6c\u4e3aselect2\u6837\u5f0f\u4e0b\u62c9\u6846 |\n| SelectMultiple2 | \u5c06\u6807\u51c6select\u590d\u9009\u6846\u8f6c\u4e3aselect2\u6837\u5f0f\u4e0b\u62c9\u5f0f\u590d\u9009\u6846 |\n| [ConfigTable](#django_power_admin.widgets.ConfigTable) | \u5065\u503c\u5bf9\u914d\u7f6e\u9879\u7f16\u8f91\u63a7\u4ef6<br />\u6570\u636ejson\u5e8f\u5217\u5316\u540e\u4fdd\u5b58\u5728TextField\u4e2d |\n| PopupConfigTable | \u5f39\u51fa\u5f0f\u5065\u503c\u5bf9\u914d\u7f6e\u9879\u7f16\u8f91\u63a7\u4ef6<br />\u6570\u636ejson\u5e8f\u5217\u5316\u540e\u4fdd\u5b58\u5728TextField\u4e2d |\n| [AllUsersSelect](#django_power_admin.widgets.AllUsersSelect) | \u7528\u6237\u9009\u62e9\u63a7\u4ef6\uff0c\u4f7f\u7528Select2\u5b9e\u73b0<br />\u63d0\u4f9b\u7528\u6237\u4fe1\u606f\u6a21\u7cca\u641c\u7d22\u529f\u80fd<br />\u4e0d\u9700\u8981\u7528\u6237\u6a21\u5757\u7ba1\u7406\u6743\u9650 |\n| `@todo` PasswordResetableWidget | \u5bc6\u7801\u91cd\u7f6e\u5b57\u6bb5\uff08\u53ea\u91cd\u7f6e\uff0c\u4e0d\u663e\u793a\uff09|\n\n### Field\u6269\u5c55\u7c7b\n\n| \u7c7b\u540d | \u4e3b\u8981\u529f\u80fd |\n| ---- | -------- |\n| MPTTModelChoiceField | MPTT\u6570\u636e\u6a21\u578b\u4e2d\u7684Parent\u5b57\u6bb5\u5173\u8054\u7684\u8868\u5355\u5b57\u6bb5\uff0c<br />\u4f7f\u7528Select2\u6837\u5f0f\u63a7\u4ef6\u3002<br />\u5efa\u8bae\u5728MPTTAdminForm\u4e2d\u4f7f\u7528 |\n| ModelChoiceFieldWithLabelProperty | \u6807\u51c6ModelChoiceField\u7684\u6269\u5c55\uff0c<br />\u652f\u6301\u4f7f\u7528\u81ea\u5b9a\u4e49\u7684\u6807\u7b7e\u51fd\u6570 |\n\n### Form\u6269\u5c55\u7c7b\n\n### ListFilter\u6269\u5c55\u7c7b\n\n| \u7c7b\u540d | \u4e3b\u8981\u529f\u80fd |\n| --- | ----- |\n| [TextInputFieldFilter](#django_power_admin.filters.TextInputFieldFilter) | \u4f7f\u7528\u6587\u672c\u6846\u7684\u8fc7\u6ee4\u6761\u4ef6\u3002 |\n| [DateRangeFilter](#django_power_admin.filters.DateRangeFilter) | \u65e5\u671f\u533a\u95f4\u8fc7\u6ee4\u6761\u4ef6\u3002 |\n\n\n## \u4f7f\u7528\u65b9\u6cd5\u8bf4\u660e\n\n### django_power_admin\u7684\u5f15\u5165\n\n*pro/settings.py*\n\n```\nINSTALLED_APPS = [\n ...\n 'django_middleware_global_request',\n 'django_static_fontawesome',\n 'django_static_jquery_ui',\n 'django_simple_tags',\n 'django_power_admin',\n ...\n]\n\nMIDDLEWARE = [\n ...\n 'django_middleware_global_request.middleware.GlobalRequestMiddleware',\n ...\n]\n\n```\n\n### <a name=\"django_power_admin.admin.PowerAdmin\u6392\u5e8f\u8bb0\u5f55\u4e0a\u4e0b\u79fb\u52a8\u673a\u5236\"></a>django_power_admin.admin.PowerAdmin\u6392\u5e8f\u8bb0\u5f55\u4e0a\u4e0b\u79fb\u52a8\u673a\u5236\n\n#### django_power_admin.admin.PowerAdmin\u6392\u5e8f\u8bb0\u5f55\u4e0a\u4e0b\u79fb\u52a8\u673a\u5236\u6548\u679c\u56fe\n\n![django_power_admin.admin.PowerAdmin\u6392\u5e8f\u652f\u6301\u6548\u679c\u9884\u89c8\u56fe](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/admin/django_power_admin_admin_sorting_preview.png)\n\n\n#### django_power_admin.admin.PowerAdmin\u6392\u5e8f\u8bb0\u5f55\u4e0a\u4e0b\u79fb\u52a8\u673a\u5236\u4f7f\u7528\u65b9\u6cd5\n\n*models.py*\n\n```\nclass SortableAdminExmapleModel(models.Model):\n title = models.CharField(max_length=64, verbose_name=\"Title\")\n display_order = models.IntegerField(null=True, blank=True, verbose_name=\"Display Order\")\n\n class Meta:\n verbose_name = \"\u6392\u5e8f\u6f14\u793a\"\n verbose_name_plural = \"\u6392\u5e8f\u6f14\u793a\"\n \n def __str__(self):\n return str(self.pk)\n\n```\n\n*admin.py*\n\n```\nfrom django.contrib import admin\n\nfrom django_power_admin.admin import PowerAdmin\n\nfrom .models import SortableAdminExmapleModel\n\n\nclass SortableAdminExmapleModelAdmin(PowerAdmin):\n list_display = [\"title\"]\n ordering = [\"display_order\"]\n changelist_object_toolbar_buttons = [\n \"django_power_admin_move_up\",\n \"django_power_admin_move_down\",\n \"read_button\",\n \"change_button\",\n \"delete_button\",\n ]\n\nadmin.site.register(SortableAdminExmapleModel, SortableAdminExmapleModelAdmin)\n\n```\n\n### <a name=\"django_power_admin.widgets.Select2\"></a>django_power_admin.widgets.Select2\n\n#### django_power_admin.widgets.Select2\u6548\u679c\u9884\u89c8\u56fe\n\n![django_power_admin.widgets.Select2\u6548\u679c\u9884\u89c8\u56fe](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/widgets/Select2/django_power_admin_widgets_select2_preview.png)\n\n#### django_power_admin.widgets.Select2\u4f7f\u7528\u65b9\u6cd5\n\n*models.py*\n\n```\nfrom django.db import models\n\nclass Select2ExampleCategory(models.Model):\n name = models.CharField(max_length=64, verbose_name=\"Name\")\n\n class Meta:\n verbose_name = \"Category\"\n verbose_name_plural = \"Categories\"\n \n def __str__(self):\n return self.name\n\nclass Select2ExampleModel(models.Model):\n title = models.CharField(max_length=64, verbose_name=\"Title\")\n category = models.ForeignKey(Select2ExampleCategory, on_delete=models.CASCADE, verbose_name=\"Category\")\n\n class Meta:\n verbose_name = \"\u53ef\u641c\u7d22\u4e0b\u62c9\u6846\u6f14\u793a\"\n verbose_name_plural = \"\u53ef\u641c\u7d22\u4e0b\u62c9\u6846\u6f14\u793a\"\n\n def __str__(self):\n return self.title\n\n```\n\n*admin.py*\n\n```\nfrom django import forms\nfrom django.contrib import admin\n\nfrom django_power_admin.widgets import Select2\n\nfrom .models import Select2ExampleCategory\nfrom .models import Select2ExampleModel\n\n\nclass Select2ExampleCategoryAdmin(admin.ModelAdmin):\n list_display = [\"name\"]\n\nclass Select2ExampleModelForm(forms.ModelForm):\n class Meta:\n widgets = {\n \"category\": Select2(),\n }\n\nclass Select2ExampleModelAdmin(admin.ModelAdmin):\n form = Select2ExampleModelForm\n list_display = [\"title\"]\n\nadmin.site.register(Select2ExampleCategory, Select2ExampleCategoryAdmin)\nadmin.site.register(Select2ExampleModel, Select2ExampleModelAdmin)\n\n```\n\n\n### <a name=\"django_power_admin.widgets.ConfigTable\"></a>django_power_admin.widgets.ConfigTable\n\n#### django_power_admin.widgets.ConfigTable\u6548\u679c\u9884\u89c8\u56fe\n\n![django_power_admin.widgets.ConfigTable\u6548\u679c\u9884\u89c8\u56fe](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/widgets/ConfigTable/django_power_admin_widgets_config_table_preview.png)\n\n#### django_power_admin.widgets.ConfigTable\u4f7f\u7528\u65b9\u6cd5\n\n*models.py*\n\n```\nfrom django.db import models\n\nclass ConfigTableExampleModel(models.Model):\n config = models.TextField(null=True, blank=True, verbose_name=\"\u914d\u7f6e\")\n \n class Meta:\n verbose_name = \"\u914d\u7f6e\u8868\u63a7\u4ef6\u6f14\u793a\"\n verbose_name_plural = \"\u914d\u7f6e\u8868\u63a7\u4ef6\u6f14\u793a\"\n\n def __str__(self):\n return str(self.pk)\n```\n\n*admin.py*\n\n```\nfrom django import forms\nfrom django.contrib import admin\n\nfrom django_power_admin.widgets import ConfigTable\n\nclass ConfigTableExampleModelForm(forms.ModelForm):\n class Meta:\n widgets = {\n \"config\": ConfigTable(),\n }\n\nclass ConfigTableExampleModelAdmin(admin.ModelAdmin):\n form = ConfigTableExampleModelForm\n\nadmin.site.register(ConfigTableExampleModel, ConfigTableExampleModelAdmin)\n```\n\n### <a name=\"django_power_admin.widgets.AllUsersSelect\"></a>django_power_admin.widgets.AllUsersSelect\n\n#### django_power_admin.widgets.AllUsersSelect\u9884\u89c8\u6548\u679c\n\n![django_power_admin.widgets.AllUsersSelect\u6548\u679c\u9884\u89c8\u56fe](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/widgets/AllUsersSelect/AllUsersSelect.png)\n\n\n#### django_power_admin.widgets.AllUsersSelect\u4f7f\u7528\u65b9\u6cd5\n\n*models.py*\n\n```\nfrom django.db import models\n\nclass Project(models.Model):\n \n owner = models.ForeignKey(global_settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name=\"+\", verbose_name=_(\"Owner\"))\n\n class Meta:\n verbose_name = \"Project\"\n verbose_name_plural = \"Projects\"\n\n def __str__(self):\n return str(self.pk)\n```\n\n*admin.py*\n\n```\nfrom django import forms\nfrom django.contrib import admin\nfrom django_power_admin.widgets import AllUsersSelect\nfrom .models import Project\n\nclass ProjectForm(forms.ModelForm):\n class Meta:\n widgets = {\n \"owner\": AllUsersSelect(),\n }\n\nclass ProjectAdmin(admin.ModelAdmin):\n form = ProjectForm\n\nadmin.site.register(Project, ProjectAdmin)\n```\n\n### <a name=\"django_power_admin.filters.TextInputFieldFilter\"></a>django_power_admin.widgets.TextInputFieldFilter\n\n#### django_power_admin.filters.TextInputFieldFilter\u9884\u89c8\u6548\u679c\n\n![django_power_admin.filters.TextInputFieldFilter\u9884\u89c8\u6548\u679c](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/filters/TextInputFieldFilter/TextInputFieldFilter.png)\n\n\n#### django_power_admin.filters.TextInputFieldFilter\u4f7f\u7528\u65b9\u6cd5\n\n```\nfrom django.contrib import admin\nfrom django_power_admin.filters import TextInputFieldFilter\n\nclass ExampleAdmin(admin.ModelAdmin):\n list_filter = [\n (\"title\", TextInputFieldFilter),\n \"description\",\n \"enable\",\n ]\n list_display = [\"title\", \"description\", \"enable\"]\n```\n\n#### <a name=\"django_power_admin.filters.TextInputFieldFilter\u5b9e\u73b0\u539f\u7406\"></a>django_power_admin.filters.TextInputFieldFilter\u5b9e\u73b0\u539f\u7406\n\n\u4f7f\u7528\u4e86django_power_admin\u5f15\u5165\u7684ListFilter Media\u673a\u5236\uff0c\n\u901a\u8fc7\u5728\u7c7b\u5185\u90e8\u5b9a\u4e49`class Media`\uff0c\n\u5bfc\u5165ListFilter\u9700\u8981\u4f7f\u7528\u5230\u7684js/css\u6587\u4ef6\uff0c\n\u5bfc\u5165\u7684js\u6587\u4ef6\uff0c\u53ef\u4ee5\u6309django\u6807\u51c6media\u6587\u4ef6\u5f15\u5165\u673a\u5236\u8fdb\u884c\u81ea\u52a8\u5316\u7684\u53bb\u91cd\u548c\u4f9d\u8d56\u6392\u5e8f\u3002\n\n\n```\nfrom django.contrib.admin import FieldListFilter\n\nclass TextInputFieldFilter(FieldListFilter):\n template = 'django_power_admin/filters/TextInputFieldFilter.html'\n\n ...\n\n class Media:\n css = {\n \"all\": [\n \"django_power_admin/filters/TextInputFieldFilter/css/TextInputFieldFilter.css\",\n ]\n }\n js = [\n \"django_power_admin/assets/js/parseParam.js\",\n \"admin/js/vendor/jquery/jquery.js\",\n \"django_power_admin/filters/TextInputFieldFilter/js/TextInputFieldFilter.js\",\n \"admin/js/jquery.init.js\",\n ]\n\n```\n\n### <a name=\"django_power_admin.filters.DateRangeFilter\"></a>django_power_admin.filters.DateRangeFilter\n\n#### django_power_admin.filters.DateRangeFilter\u6548\u679c\u9884\u89c8\n\n![django_power_admin.filters.DateRangeFilter](https://github.com/zencore-dobetter/pypi-images/raw/main/django-power-admin/filters/DateRangeFilter/DateRangeFilter.png)\n\n\n#### django_power_admin.filters.DateRangeFilter\u4f7f\u7528\u65b9\u5f0f\n\n```\nfrom django.contrib import admin\nfrom django_power_admin.filters import DateRangeFilter\n\nclass ExampleAdmin(admin.ModelAdmin):\n list_filter = [\n \"username\",\n (\"date_join\", DateRangeFilter),\n \"is_active\",\n ]\n list_display = [\"username\", \"date_join\", \"is_active\"]\n```\n\n### Admin\u6837\u5f0f\u7c7b\n\n- inline-narror-input\n\n TabularInline\u5b57\u7b26\u4e32\u8f93\u5165\u6846\u6539\u4e3a\u5c0f\u6846\u3002\n\n *\u4f7f\u7528\u8303\u56f4\uff1a*\n\n - \u53ef\u52a0\u5728TabularInline\u7c7b\u7684claases\u5c5e\u6027\u4e2d\u3002\n\n- related-actions-hidden\n\n \u9690\u85cf\u5916\u952e\u7684\u589e\u6539\u5220\u6309\u94ae\u3002\n\n *\u4f7f\u7528\u8303\u56f4\uff1a*\n\n - \u53ef\u52a0\u5728fieldsets\u7684classes\u5c5e\u6027\u4e2d\u3002\n - \u53ef\u4ee5\u52a0\u5728TabularInline\u7c7b\u7684claases\u5c5e\u6027\u4e2d\u3002\n\n- inline-original-hidden\n\n \u9690\u85cfTabularInline\u53caStackInline\u4e2d\u7684orininal\u663e\u793a\u3002\n\n *\u4f7f\u7528\u8303\u56f4\uff1a*\n\n - \u53ef\u52a0\u5728TabularInline\u7c7b\u7684claases\u5c5e\u6027\u4e2d\u3002\n - \u53ef\u52a0\u5728StackInline\u7c7b\u7684claases\u5c5e\u6027\u4e2d\u3002\n\n- form-row-c2\n\n FormChange\u8868\u5355\u4e24\u4f8b\u663e\u793a\uff0c\u540c\u65f6\u63a7\u5236textarea\u7684\u5bbd\u5ea6\u3002\n\n *\u4f7f\u7528\u8303\u56f4\uff1a*\n\n - \u53ef\u52a0\u5728fieldsets\u7684classes\u5c5e\u6027\u4e2d\u3002\n\n### Admin\u5168\u5c40\u63a7\u5236\n\n- DJANGO_ADMIN_USE_FIXED_WIDTH_LAYOUT\n\n \u5f53DJANGO_ADMIN_USE_FIXED_WIDTH_LAYOUT=True\uff0cAdmin\u7ba1\u7406\u540e\u53f0\u8bbe\u7f6e\u4e3a\u56fa\u5b9a\u5bbd\u5ea6\uff0c\u4e14\u5c45\u4e2d\u663e\u793a\u3002\u53ef\u901a\u8fc7\u4ee5\u4e0b\u8bbe\u7f6e\u63a7\u5236\u5bbd\u5ea6\u53ca\u80cc\u666f\u8272\u3002\n\n *\u5173\u8054\u8bbe\u7f6e\u9879\uff1a*\n\n - DJANGO_ADMIN_USE_FIXED_WIDTH_LAYOUT = False\n - DJANGO_ADMIN_WIDTH = 1280px\n - DJANGO_ADMIN_BACKGROUND_COLOR = \"#f5f6f8\"\n - DJANGO_ADMIN_FOOTER_COLOR = \"#c5cbd2\"\n\n\n## \u7248\u672c\u8bb0\u5f55\n\n### v0.1.7\n\n- \u9879\u76ee\u542f\u52a8\u3002\n- \u6846\u67b6\u642d\u5efa\u3002\n- PowerAdmin\u7c7b\u57fa\u672c\u5b8c\u6210\u3002\n\n### v0.1.10\n\n- get_extra_views\u66f4\u540d\u4e3aget_extra_view_urls\uff0c\u907f\u514d\u4e0e\u5176\u5b83\u65b9\u6cd5\u540d\u51b2\u7a81\u3002\n- view_action\u66f4\u540d\u4e3aread_xxx\u3002xxx_action\u66f4\u540d\u4e3axxx_button\u3002\n- \u5728list_display\u4e2d\u8ffd\u52a0change_list_object_toolbar\u5b57\u6bb5\u3002\n\n### v0.1.12\n\n- \u589e\u52a0has_change_permission_real, has_delete_permission_real\u65b9\u6cd5\uff0c\u89e3\u51b3read/change\u673a\u5236\u5bfc\u81f4\u7684\u539f\u59cb\u6743\u9650\u5224\u65ad\u4e22\u5931\u7684\u60c5\u51b5\u3002\n- \u589e\u52a0get_messages\u65b9\u6cd5\uff0c \u7528\u4e8e\u83b7\u53d6\u7ad9\u70b9\u5f53\u524d\u7684messages\u961f\u5217\u3002\n- \u589e\u52a0get_power_admin_class\uff0c\u7528\u4e8e\u7edf\u4e00\u6269\u5c55\u6240\u6709PowerAdmin\u7684\u5b50\u7c7b\u3002\n\n### v0.1.18\n\n- \u4fee\u6b63get_changelist_object_row_classes_javascript\u65b9\u6cd5\u5728\u9047\u5230\u5176\u5b83\u9519\u8bef\u65f6\u5bfc\u81f4\u7684\u5f02\u5e38\u884c\u4e3a\u3002\n- ChangelistObjectToolbarButton\u53ef\u4ee5\u76f4\u63a5\u5f15\u7528extra view\uff08\u9700\u8981\u4e3aextra view\u6dfb\u52a0\u6309\u94ae\u989d\u5916\u5c5e\u6027\uff0c\u5982\uff1ashort_description\u3001icon\u3001classes\u7b49\uff09\u3002\n- change_list_xxx\u66f4\u540d\u4e3achangelist_xxx\uff08\u6ce8\u610f\uff1a\u53ef\u80fd\u5f15\u8d77\u65b0\u65e7\u7248\u672c\u7684\u4e0d\u517c\u5bb9\uff0c\u7279\u522b\u662f\u5b50\u7c7b\u914d\u7f6e\u7684change_list_toolbar_buttons\u5c5e\u6027\u9700\u8981\u6539\u540d\u4e3achangelist_toolbar_buttons\uff09\u3002\n- \u5f15\u5165ChangelistToolbar\u673a\u5236\uff0c\u7528\u4e8e\u6dfb\u52a0\u989d\u5916\u7684\u5217\u8868\u9875\u9876\u90e8\u6309\u94ae\u3002\n\n### v0.1.20\n\n- \u6dfb\u52a0\u7b80\u6613\u6570\u636e\u5206\u4eab\u673a\u5236\u7684\u652f\u6301\uff08simple share model\uff09\u3002\n- \u6dfb\u52a0\u6570\u636e\u5bfc\u51fa\u529f\u80fd\u3002\n\n### v0.1.21\n\n- \u6dfb\u52a0\u9002\u7528\u4e8eTextField\u4f7f\u7528\u7684\u201c\u952e\u503c\u5bf9\u201d\u63a7\u4ef6\u3002\n- PowerAdmin\u4e2d\u65b9\u6cd5\u540d\u52a0\u4e0adjango_power_admin_\u524d\u7f00\uff0c\u907f\u514d\u4e0e\u5176\u5b83\u6269\u5c55\u7c7b\u51b2\u7a81\u3002\n\n### v0.1.23\n\n- \u4fee\u6b63Select2\u3001SelectMultiple2\u3001ConfigTable\u5728inline\u8868\u5355\u4e2d\u7684\u4f7f\u7528\u95ee\u9898\u3002\n- \u65b0\u589edjango_power_admin.widgets.AllUsersSelect\u3002\n\n### v0.1.24\n\n- \u65b0\u589edjango_power_admin.filters.TextInputFieldFilter\u3002\n- \u65b0\u589elist_filter\u7c7b\u901a\u8fc7\u5b9a\u4e49\u5185\u90e8\u7684`Media:`\u5f15\u5165\u989d\u5916\u7684js/css\u6587\u4ef6\u7684\u673a\u5236\u3002\n\n### v0.1.25\n\n- \u65b0\u589edjango_power_admin.filters.DateRangeFilter\u3002\n\n### v0.1.27\n\n- \u4fee\u6b63ChangelistObjectToolbar\u6309\u94ae\u6362\u884c\u7684\u95ee\u9898\u3002\n\n### v0.1.29\n\n- \u517c\u5bb9django 4.x\u3002\n- \u517c\u5bb9python 2.7\u3002\n- \u4fee\u6b63\u6392\u5e8fAdmin\u672a\u8bbe\u7f6eordering\u65f6\u7684\u5f02\u5e38\u3002\n\n### v0.1.30\n\n- \u4fee\u6b63get_ordering\u5f3a\u5236\u6dfb\u52a0display_order\u5b57\u6bb5\u5bfc\u81f4\u7684\u95ee\u9898\u3002\n\n### v0.1.31\n\n- \u4fee\u6b63ChangelistObjectToolBarButton\u7684\u9ed8\u8ba4target=self\u95ee\u9898\uff0c\u4fee\u6b63\u540e\u7684\u9ed8\u8ba4target=_self\u3002\n- \u4f7f\u7528zenutils\u4f9d\u8d56\u5305\u4ee5\u7b80\u5316\u4e0d\u5fc5\u8981\u7684\u4f9d\u8d56\u5173\u7cfb\u3002\n\n### v0.1.35\n\n- \u4fee\u6b63DateRangeFilter\u7ed3\u675f\u65e5\u671f\u6846\u641c\u7d22\u6761\u4ef6\u540d\u79f0\u9519\u8bef\u7684\u95ee\u9898\u3002\n\n### v0.1.36\n\n- \u589e\u52a0\u7ad9\u70b9\u56fa\u5b9a\u5bbd\u5ea6\u5c45\u4e2d\u3002\n- \u589e\u52a0Admin\u6837\u5f0f\u7c7b\uff1aform-row-c2\u3001inline-original-hidden\u3001related-actions-hidden\u3001inline-narror-input\u3002\n- \u589e\u52a0PopupConfigTable\u63a7\u4ef6\u3002\n\n### v0.1.37\n\n- \u6587\u6863\u66f4\u65b0\u3002\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Django\u63d0\u4f9b\u4e86\u5feb\u6377\u7684\u751f\u6210\u540e\u53f0\u7ba1\u7406\u7ad9\u70b9\u7684\u80fd\u529b\u3002\u672c\u5e94\u7528\u65e8\u5728\u589e\u5f3aDjango Admin\u7684\u80fd\u529b\uff0c\u63d0\u4f9b\u4e30\u5bcc\u7684Admin\u3001Widget\u3001ListFilter\u3001Form\u7b49\u7b49\u754c\u9762\u6269\u5c55\u7c7b\uff0c\u540c\u65f6\u4e5f\u4e3a\u5e38\u7528\u7684\u6570\u636e\u7ba1\u7406\u6a21\u578b\u63d0\u4f9b\u5b8c\u6574\u7684\u7ba1\u7406\u529f\u80fd\u3002",
"version": "0.1.37",
"project_urls": null,
"split_keywords": [
"django",
"django admin",
"django power admin",
"django admin extensions"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bf3023f2b785dfeb5e10262a8090086b9d13d04eb699edd614ebc248a7645db7",
"md5": "37bf5c121aadc53c13cdfac3a86c4152",
"sha256": "87aeb34d9e447b2f738d344c1682a6e38f2bf07b2853dd4b1e6f28a1d912f214"
},
"downloads": -1,
"filename": "django_power_admin-0.1.37-py3-none-any.whl",
"has_sig": false,
"md5_digest": "37bf5c121aadc53c13cdfac3a86c4152",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 50282,
"upload_time": "2023-09-14T12:41:45",
"upload_time_iso_8601": "2023-09-14T12:41:45.446381Z",
"url": "https://files.pythonhosted.org/packages/bf/30/23f2b785dfeb5e10262a8090086b9d13d04eb699edd614ebc248a7645db7/django_power_admin-0.1.37-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ca5b18440bf9b0a538d109be7e4db1188e999f5b3db4668d0822a1f2eba99073",
"md5": "379cb99443847ef00aa147432211d465",
"sha256": "fe34b7b1865c47780dac4ed2cd76beb36ee9b276bd0baa25b6e4adb15bbb1c37"
},
"downloads": -1,
"filename": "django-power-admin-0.1.37.tar.gz",
"has_sig": false,
"md5_digest": "379cb99443847ef00aa147432211d465",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 42746,
"upload_time": "2023-09-14T12:41:48",
"upload_time_iso_8601": "2023-09-14T12:41:48.259187Z",
"url": "https://files.pythonhosted.org/packages/ca/5b/18440bf9b0a538d109be7e4db1188e999f5b3db4668d0822a1f2eba99073/django-power-admin-0.1.37.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-09-14 12:41:48",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "django-power-admin"
}