django框架配备了一个强大的管理站点,其中管理站点所需的许多操作都是预定义的,但有时默认操作可能不符合要求。例如,如果所选对象需要批量更新,则有必要编写一个自定义操作实现。本文以django的官方英文文档为基础,对定制管理操作中需要做的工作进行梳理,从而快速了解定制管理操作的实施过程。
作者|山雨,编辑|雷蒙
由| CSDN制作
管理操作简介
管理操作是可以在管理站点的下拉列表中选择和执行的简单功能,例如删除对象。
写入管理操作
以下示例显示了如何编写管理操作。例如,批量更新名为Article的模型:
fromdjango.dbimportmodels
状态_选择=
分类文章:
标题=模型。类型
body =模型。文本字段
状态=型号。类型
def__str__:
返回自我标题
让我们编写action函数,它接受三个函数:
当前模型管理
表示当前http请求的HTTPrequest对象
包含用户选择的对象的查询集:
queryset.update
为了达到最佳性能,建议使用QuerySet的更新方法。
forobjinqueryset:
用做某事
默认情况下,该操作会以“Make published”的形式出现在操作列表中,这是函数名,下划线会被空替换。为了使这个方法更容易理解,我们可以给它添加一个short_description属性。
defmake_published:
queryset.update
make _ published . short _ description = "将选定的故事标记为已发布"
向模型管理添加操作
完整的程序如下:
fromdjango.contribimportadmin
frommyapp.modelsimportArticle
defmake_published:
queryset.update
make _ published . short _ description = "将选定的故事标记为已发布"
类别文章管理员:
列表_显示=
排序=
动作=
admin.site.register
效果如下:
处理行动中的错误
将动作定义为模型管理的内部方法
上面定义的动作的一个缺点是它与Article对象紧密耦合,这将导致大量重复的代码,即使这些动作的功能是相同的。将动作定义为ModelAdmin的方法可以避免这个问题。
修改上面的文章管理员:
类别文章管理员:
...
动作=
defmake_published:
queryset.update
make _ published . short _ description = "将选定的故事标记为已发布"
请注意,make_published成为ArticleAdmin的内部方法,第一个参数成为self。将动作转换成ModelAdmin的方法,这样它就可以调用Admin提供的任何方法。例如,向用户发送消息:
类别文章管理员:
...
defmake_published:
rows _ updated = queryset.update
ifrows_updated ==1:
message _ bit =“1个故事是”
否则:
message _ bit =“% s”故事被“% rows _ updated”
self.message_user
这使得操作在成功执行后自动匹配管理站点的行为。
效果如下:
提供中间页面的操作
在某些情况下,action需要提供一个中间页面来提示用户是否确认操作,比如在删除对象时提醒用户是否确认操作:
要提供中间页面,您只需要返回一个HttpResponse或子类。例如,导出选定对象的json文件的操作:
from django . coreimportserializer
fromdjango.httpimportHttpResponse
defexport_as_json:
响应= HttpResponse
序列化程序
返回响应
然而,这可能会使行动的逻辑变得非常复杂。推荐的方法是返回一个HTTP重定向到一个新的页面,这样就可以在页面的视图中执行更复杂的逻辑,从而避免动作充满复杂的逻辑。
fromdjango.contribimportadmin
from django . contrib . content types . modelsimportcontenttype
from django . httproporthtpresponseseredirect
defexport_selected_objects:
选定=请求。POST.getlist
CT = ContentType . objects . get _ for _ model
returnHttpResponseRedirect))
使行动在整个站点有效
如果希望上述导出操作在整个管理站点都可用,可以这样做:
为了方便管理这个操作,比如用代码去掉这个操作,可以给它取一个名字
禁用操作
禁用站点范围的操作:
这将在整个管理站点禁用该操作。
如果需要重用禁用的操作。您只需要在相应模型管理的操作属性中添加此操作。例如,重用上述禁用的操作:
#这个会#
类另一个模型管理员:
动作=
要禁用模型管理中的所有操作,只需将操作属性设置为无。
类模型管理:
操作=无
有条件地启用或禁用操作
通过重写模型管理的get_actions方法,可以有条件地启用或禁用操作。这个方法返回一个允许的动作字典,键是动作的名称,值是一个元组。例如,如果您只希望名称以“j”开头的用户能够批量删除对象:
设置操作权限
操作可以通过设置allowed_permissions属性来限制具有特定权限的用户的可用性:
efmake_published:
queryset.update
make _ published . allowed _ permissions =
如果allowed_permissions具有多个权限,则只要用户至少通过一次权限检查,操作就可用。allowed_permissions的可用值为:
增加
变化
删除
视角
如果需要指定其他值,则需要在模型管理中定义一个haspermission方法,例如:
fromdjango.contribimportadmin
from django . contrib . authimportget _ permission _ codename
类别文章管理员:
动作=
defmake_published:
queryset.update
make _ published . allowed _ permissions =
defhas_publish_permission:
" " "用户有发布权限吗?"""
opts =self.opts
code name = get _ permission _ code name
returnrequest.user.has_perm)
最后附上正式文件地址:https://docs . djangproject . com/zh-Hans/2.2/ref/contrib/admin/actions/