zoukankan      html  css  js  c++  java
  • django后台管理--添加自定义action

    管理员动作

    简单来说,Django管理员的基本工作流程是“选择一个对象,然后进行更改”。这对大多数用例都很有效。 然而当你一次性要对多个对象做相同的改变,这个流程是非常的单调乏味的。

    在这些情况下,Django Admin 可以让你编写并注册“Action” —— 仅仅只是一个以更改列表页面上选中对象的列表为参数的回调函数。

    django自带了一个删除操作的动作:

    通过官网的一个实例来说明自定义action的用法:

    任务的目标: 批量操作,把文章的状态更新为已发布

    #一个数据库模型如下
    STATUS_CHOICES = ( ('d', 'Draft'), ('p', 'Published'), ('w', 'Withdrawn'), ) class Article(models.Model): title = models.CharField(max_length=50) body = models.CharField(max_length=300) editor = models.CharField(max_length=30, null=True) status = models.CharField(max_length=1, choices=STATUS_CHOICES) def __unicode__(self): return self.title

    编写action

    首先,我们需要定义一个函数,当在Admin 界面上触发该Action 的时候调用。 Action 函数,跟普通的函数一样,需要接收三个参数:

    • 当前的 ModelAdmin
    • 表示当前请求的HttpRequest
    • 含有用户所选的对象集合的QuerySet
    def make_published(modeladmin, request, queryset):
        queryset.update(status='p')
    
    
    make_published.short_description = "Mark selected stories as published"
    
    
    class ArticleAdmin(admin.ModelAdmin):
        actions_on_top = True
        actions_selection_counter = True
        list_display = ["title", "body", "editor", "status"]
        actions = [make_published]

    #make_published.short_description,下垃操作中默认是展示make_published,定义short_description可以以一种友好的方式展示。

    前端展示如下:

    处理错误

    这其中,如果你能够预知在自定义的操作中可能产生的错误,请处理该错误,并通过django.contrib.admin.ModelAdmin.message_user()以友好的方式给予用户提示信息。

    将action定义为modeladmin的方法:

    上面的例子展示了定义为一个简单函数的make_published操作。 这真是极好的,但是以视图的代码设计角度来看,它并不完美:由于操作与Article紧密耦合,不如将操作直接绑定到ArticleAdmin对象上更有意义。

    我们上面定义的make_published方法,第一个参数是modeladmin对象,把要操作的modeladmin对象作为参数传递给make_published

    class ArticleAdmin(admin.ModelAdmin):
        actions_on_top = True
        actions_selection_counter = True
        list_display = ["title", "body", "editor", "status"]
    
        def make_published(self, request, queryset):
            queryset.update(status='d')
    
        make_published.short_description = "Mark selected stories as published"
        actions = [make_published]

    这样做的好处是自定义方法可以直接访问类本身。例如下面使用self引用,为方法添加提示信息的功能:下面加入了一些提示信息:

    class ArticleAdmin(admin.ModelAdmin):
        actions_on_top = True
        actions_selection_counter = True
        list_display = ["title", "body", "editor", "status"]
    
        def make_published(self, request, queryset):
            rows_updated = queryset.update(status='d')
            if rows_updated == 1:
                message_bit = "1 story was"
            else:
                message_bit = "%s stories were" % rows_updated
            self.message_user(request, "%s successfully marked as published." % message_bit)
    
        make_published.short_description = "Mark selected stories as published"
        actions = [make_published]

    展示如下:

    跳转中间页面

    把操作的数据跳转到另一个视图界面,然后进行操作。

    默认情况下,执行完actions后,浏览器会返回先前的修改列表页面。但有时候,一些复杂的action需要返回中间页面,例如内置的删除方法,在执行删除动作之前,会弹出一个删除确认页面。

    要实现这个功能,只需要在action方法中返回一个HttpResponse(或它的子类)。 例如下面是一个利用Django内置的序列化函数将一个对象保存为json格式的范例:

    from django.http import HttpResponse
    from django.core import serializers
    
    def export_as_json(modeladmin, request, queryset):
        response = HttpResponse(content_type="application/json")
        serializers.serialize("json", queryset, stream=response)
        return response

    多数情况下,我们会使用HttpResponseRedirect跳转到一个中间页面,并在GET方法的url中携带别选择的对象作为参数传递过去,然后在这个新的视图中接收这个参数,并编写具体的更加复杂的业务逻辑,如下面的代码所示:

    from django.contrib import admin
    from django.contrib.contenttypes.models import ContentType
    from django.http import HttpResponseRedirect
    
    def export_selected_objects(modeladmin, request, queryset):
        # 获得被打钩的checkbox对应的对象
        selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
        # 获取对应的模型
        ct = ContentType.objects.get_for_model(queryset.model)
        # 构造访问的url,使用GET方法,跳转到相应的页面
        return HttpResponseRedirect("/export/?ct=%s&ids=%s" % (ct.pk, ",".join(selected)))

    编写可用于整个admin站点的action

    前面创建的actions智能应用于绑定的模型。实际上有时候,我们还需要可以对admin站点内所有模型都有效的acitons。上面写的export_selected_objects函数可以是一个很好的例子。要实现这一功能,你需要使用内置的AdminSite.add_action方法:

    from django.contrib import admin
    
    admin.site.add_action(export_selected_objects)

    禁用action

    有时候,对于某些actions,我们想全局禁用或者局部禁用它。需要使用AdminSite.disable_action(name)方法。

    • 禁用全站级别的acitons:

    例如,禁用内置的删除方法:

    admin.site.disable_action('delete_selected')
    • 全站禁用,但是个别可用: 在ModelAdmin.actions中显式地引用。
      # 全站禁用删除功能
      admin.site.disable_action('delete_selected')
      
      # 这个老老实实的被禁了
      class SomeModelAdmin(admin.ModelAdmin):
          actions = ['some_other_action']
          ...
      
      # 这个声明:我还要用
      class AnotherModelAdmin(admin.ModelAdmin):
          actions = ['delete_selected', 'a_third_action']
          ...
    • 在指定模型中禁用所有actions:设置ModelAdmin.actions为None。(这会连带全局actions一起禁用了。)
      class MyModelAdmin(admin.ModelAdmin):
              actions = None
    • 根据条件自动启用或禁用:

      还可以根据条件自动选择性的启动或禁用某些acitons,你只需要改写ModelAdmin.get_actions()方法。

      该方法将返回一个包含actions的字典。字典的键是aciton的名字(也就是前面的'delete_selected', 'a_third_action'之类),值是一个元组,包含(函数、名字、别名)

      例如,允许用户名以“J”开头的用户批量删除对象,但其它用户不行:

      class MyModelAdmin(admin.ModelAdmin):
          ...
      
          def get_actions(self, request):
              actions = super(MyModelAdmin, self).get_actions(request)
              if request.user.username[0].upper() != 'J':
                  if 'delete_selected' in actions:
                      del actions['delete_selected']
              return actions
  • 相关阅读:
    centos 7 安装ntp服务器
    centos 7编译安装nodejs 6.1
    修改IKAnalyzer配置
    Elasticsearch5.5.0安装head插件
    搭建ELASTICSEARCH实现中文分词搜索功能
    0426HTML基础:标签
    事件事件流
    纯css设置各行变色
    dom操作之元素的增删复制
    dom操作
  • 原文地址:https://www.cnblogs.com/wxzhe/p/10331034.html
Copyright © 2011-2022 走看看