自定义django的admin后台action

自定义django的admin后台action

django的admin后台管理系统中自带了一个批量删除所选对象的action。
“批量删除”action
我们还可以添加自定义的action来实现其它类似的功能,如批量修改某个字段的功能。
简单的,例如将文章批量标记为已发布的action,如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
from django.contrib import admin
from myapp.models import Article
 
def make_published(modeladmin, request, queryset):
     queryset.update(status = 'p' )
make_published.short_description = "Mark selected stories as published"  #这里的短描述是action下拉框中显示的描述
 
class ArticleAdmin(admin.ModelAdmin):
     list_display = [ 'title' , 'status' ]
     ordering = [ 'title' ]
     actions = [make_published]
 
admin.site.register(Article, ArticleAdmin)

上诉例子中的action比较简单,执行action时也不需要用户输入,实际上更常见的action是需要用户的输入或选择的。例如一个model A中有个外键foreign key关联另一个model B,我希望能有一个action可以批量更改A关联的B对象。对于这种情况,django官方文档中推荐的做法是重定向至另一个View中,并将所需的item id等作为GET query参数传递过去,在另一个View中处理复杂的逻辑,如让用户输入等。
注意到默认的删除action也是需要用户输入的(确认或取消操作),也有另外的页面,但是这个页面的url确实和原先的共用的,也就是说没有完全像文档中推荐的那样有另外一个View。是怎么做到的呢?
直接上代码吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from django.contrib import admin, messages
from django import forms
from myApp.models import DataSrc
 
class CaseAdmin(admin.ModelAdmin):
   form = CaseForm
   actions = [ 'update_data_src' ]
 
   class data_src_form(forms.forms.Form):
     _selected_action = forms.CharField(widget = forms.MultipleHiddenInput)
     data_src = forms.ModelChoiceField(DataSrc.objects)
 
####################################
 
def update_data_src(modeladmin, request, queryset):
   form = None
   if 'cancel' in request.POST:
     modeladmin.message_user(request, u '已取消' )
     return
   elif 'data_src' in request.POST:
     form = modeladmin.data_src_form(request.POST)
     if form.is_valid():
       data_src = form.cleaned_data[ 'data_src' ]
       for case in queryset:
         case.data_src = data_src
         case.save()
       modeladmin.message_user(request, "%s successfully updated." % queryset.count())
       return HttpResponseRedirect(request.get_full_path())
     else :
       messages.warning(request, u "请选择数据源" )
       form = None
 
   if not form:
     form  = modeladmin.data_src_form(initial = { '_selected_action' : request.POST.getlist(admin.ACTION_CHECKBOX_NAME)})
   return render_to_response( 'batch_update.html' ,
                                   { 'objs' : queryset, 'form' : form, 'path' :request.get_full_path(), 'action' : 'update_data_src' , 'title' : u '批量修改数据源为' },
                                   context_instance = RequestContext(request)
         )
 
update_data_src.short_description = u '批量修改 数据源'

batch_update.html如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{% extends "admin/base_site.html" %}
 
{% block content %}
     < form method = "post" action = "{{ path }}" >
         {% csrf_token %}
         {{ form }}
         < p >
             < input type = "hidden" name = "action" value = "{{ action }}" />
             < input type = "submit" name = "cancel" value = "取消" />
             < input type = "submit" value = "确定" />
         </ p >
     </ form >
     < p >将批量修改以下所有对象</ p >
     < ul >
         {% for obj in objs %}
             < li >{{ obj }}</ li >
         {% endfor %}
     </ ul >
{% endblock %}

简而言之,就是在action中,首先返回一个用户输入(选择)的页面,此页面包含一个form,此form将submit至原先的url,form中包含_selected_action为用户已选择的id,以及action为用户选择的action名(即模拟原先的页面中form表单中的必须元素)。这时候用户再submit时,可识别出用户已经选择了,此时再执行想要的批量操作即可。

reference
http://www.hoboes.com/Mimsy/hacks/django-actions-their-own-intermediate-page/
django官方文档

本文出自夜惊心的博客,转载请保留出处

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值