您的位置:首页 > 编程语言 > Go语言

自定义django的admin后台action

2015-04-02 09:28 183 查看

django的admin后台管理系统中自带了一个批量删除所选对象的action。 

我们还可以添加自定义的action来实现其它类似的功能,如批量修改某个字段的功能。简单的,例如将文章批量标记为已发布的action,如下:

1 from django.contrib import admin
2 from myapp.models import Article
3
4 def make_published(modeladmin, request, queryset):
5     queryset.update(status='p')
6 make_published.short_description = "Mark selected stories as published"  #这里的短描述是action下拉框中显示的描述
7
8 class ArticleAdmin(admin.ModelAdmin):
9     list_display = ['title', 'status']
10     ordering = ['title']
11     actions = [make_published]
12
13 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 from django.contrib import admin, messages
2 from django import forms
3 from myApp.models import DataSrc
4
5 class CaseAdmin(admin.ModelAdmin):
6   form = CaseForm
7   actions = ['update_data_src']
8
9   class data_src_form(forms.forms.Form):
10     _selected_action = forms.CharField(widget=forms.MultipleHiddenInput)
11     data_src = forms.ModelChoiceField(DataSrc.objects)
12
13
14
15 def update_data_src(modeladmin, request, queryset):
16   form = None
17   if 'cancel' in request.POST:
18     modeladmin.message_user(request, u'已取消')
19     return
20   elif 'data_src' in request.POST:
21     form = modeladmin.data_src_form(request.POST)
22     if form.is_valid():
23       data_src = form.cleaned_data['data_src']
24       for case in queryset:
25         case.data_src = data_src
26         case.save()
27       modeladmin.message_user(request, "%s successfully updated." % queryset.count())
28       return HttpResponseRedirect(request.get_full_path())
29     else:
30       messages.warning(request, u"请选择数据源")
31       form = None
32
33   if not form:
34     form  = modeladmin.data_src_form(initial={'_selected_action': request.POST.getlist(admin.ACTION_CHECKBOX_NAME)})
35   return render_to_response('batch_update.html',
36                                   {'objs': queryset, 'form': form, 'path':request.get_full_path(), 'action': 'update_data_src', 'title': u'批量修改数据源为'},
37                                   context_instance=RequestContext(request)
38         )
39
40 update_data_src.short_description = u'批量修改 数据源'

batch_update.html如下:

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

django官方文档

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: