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
  • 相关阅读:
    mojo 接口示例
    MojoliciousLite: 实时的web框架 概述
    接口返回json
    centos 6.7 perl 版本 This is perl 5, version 22 安装DBI DBD
    centos 6.7 perl 5.22 安装DBD 需要使用老的perl版本
    商业智能改变汽车行业
    商业智能改变汽车行业
    读MBA经历回顾(上)目的决定手段——北漂18年(48)
    perl 升级到5.20版本
    Group Commit of Binary Log
  • 原文地址:https://www.cnblogs.com/wxzhe/p/10331034.html
Copyright © 2011-2022 走看看