Django 进阶 之 自定义Actions
Django的Model的Admin管理页面上一般都有一个删除选中行的下拉框选项,用于批量删除选中的记录
在应用中,只这一项操作往往还不足以更好的使用,需要自定义一些应用于实际情况的批量操作
一、 把Actions方法定义到modelAdmin类外部,可以应用到多个model上
1 from django.contrib import admin 2 from .models import Poem,ToDo 3 4 5 ''' 6 modeladmin:是当前的modeladmin 7 request:是http请求 8 queryset:是用户所选对象的集合 9 ''' 10 def print_poem(modeladmin, request, queryset): 11 for qs in queryset: 12 print(qs) 13 14 def set_type_action(modeladmin, request, queryset): 15 for qs in queryset: 16 qs.type = 2 17 qs.save() 18 set_type_action.short_description='设为宋词' #给事件添加自定义描述 19 20 class PoemModelAdmin(admin.ModelAdmin): 21 list_display = ('title','author','type') #定制显示字段 22 list_display_links = ['author',] #定制点击内容到修改页面的字段 23 search_fields = ['title','author'] #定制搜索字段 24 list_editable = ['title',] #定制列表页上可编辑的字段(同一字段不可以是既可链接又可编辑的) 25 list_filter = ['author',] #定制可过滤字段 26 27 # 注册行为操作 28 actions = [print_poem, set_type_action] 29 30 class Meta: 31 model = Poem 32 33 34 admin.site.register(Poem, PoemModelAdmin)
二、 如果Action方法的操作只能应用于某一个Model,则可以把Actions方法放到modelAdmin类中
1 from django.contrib import admin 2 from .models import Poem,ToDo 3 4 class PoemModelAdmin(admin.ModelAdmin): 5 list_display = ('title','author','type') #定制显示字段 6 list_display_links = ['author',] #定制点击内容到修改页面的字段 7 search_fields = ['title','author'] #定制搜索字段 8 list_editable = ['title',] #定制列表页上可编辑的字段(同一字段不可以是既可链接又可编辑的) 9 list_filter = ['author',] #定制可过滤字段 10 11 # 把行为方法定义到类内部中 12 def print_poem(self, request, queryset): 13 for qs in queryset: 14 print(qs) 15 16 def set_type_action(self, request, queryset): 17 for qs in queryset: 18 qs.type = 2 19 qs.save() 20 self.message_user(request,'成功更新%d条记录'% len(queryset)) 21 22 set_type_action.short_description = '设为宋词' # 给事件添加自定义描述 23 24 # 注册行为操作 25 actions = [print_poem, set_type_action] 26 # actions = None #禁用actions操作,将不显示actions下拉框 27 28 class Meta: 29 model = Poem 30 31 32 admin.site.register(Poem, PoemModelAdmin)
三、 如果对model进行的操作需要有一个中间页面来判断选择,就像批量删除的那个中间页面那样,可以使用下面的方法
1 from django import forms 2 from .models import Poem, AddPdfFileModel 3 4 class SetTypeForm(forms.Form): 5 type = forms.IntegerField() 6 _selected_action = forms.CharField(widget=forms.MultipleHiddenInput) #这个字段是必需的,表示选择了多少项
1 {% extends 'admin/base_site.html' %} 2 3 {% load i18n admin_urls %} 4 5 {% block content %} 6 <form action="" method="post">{% csrf_token %} 7 {{ form.as_p }} 8 <ul> 9 {% for ob in objects %} 10 <li>{{ ob }}</li> 11 {% endfor %} 12 </ul> 13 <!--此项表明要提交的操作是一个action,只对应要提交的action --> 14 <input type="hidden" name="action" value="set_type_action2"> 15 <!--此项是为了让处理函数识别出是提交过来的--> 16 <input type="hidden" name="post" value="yes"> 17 <input type="submit" value="提交"> 18 </form> 19 {% endblock %}
1 from django.contrib import admin 2 from .models import Poem,ToDo 3 from .forms import SetTypeForm 4 5 class PoemModelAdmin(admin.ModelAdmin): 6 list_display = ('title','author','type') #定制显示字段 7 list_display_links = ['author',] #定制点击内容到修改页面的字段 8 search_fields = ['title','author'] #定制搜索字段 9 list_editable = ['title',] #定制列表页上可编辑的字段(同一字段不可以是既可链接又可编辑的) 10 list_filter = ['author',] #定制可过滤字段 11 12 def set_type_action2(self,request, queryset): 13 if request.POST.get('post'): 14 form = SetTypeForm(request.POST) 15 if form.is_valid(): 16 type = form.cleaned_data['type'] 17 for qs in queryset: 18 qs.type = type 19 qs.save() 20 self.message_user(request,'成功更新%d条记录' % len(queryset)) 21 return None 22 else: 23 return render(request, 'manage/set_type.html', 24 {'form':SetTypeForm(initial={ 25 '_selected_action':request.POST.getlist(admin.ACTION_CHECKBOX_NAME) 26 }), 'objects': queryset}) 27 28 set_type_action2.short_description='批量设类型' 29 30 # 注册行为操作 31 actions = [print_poem, set_type_action, set_type_action2] 32 # actions = None #禁用actions操作,将不显示actions下拉框 33 34 class Meta: 35 model = Poem 36 37 38 admin.site.register(Poem, PoemModelAdmin)
四、 自定义全局的Action方法,可以应用于所有的model
1 def say_hello(modeladmin, request, queryset): 2 print('Hello') 3 4 admin.site.add_action(say_hello, '全局方法1')
五、 全局禁用某个方法
admin.site.disable_action('delete_selected') #全局禁用某个方法
六、 在某个model中不想显示和使用某个全局方法
1 #如果在当前model下不想显示全局的某个方法,可使用下面的方式控制 2 def get_actions(self, request): 3 actions = super(PoemModelAdmin, self).get_actions(request) 4 if '全局方法1' in actions: 5 del actions['全局方法1'] 6 return actions

浙公网安备 33010602011771号