django admin 扩展

添加自定义动作:

例子,添加一个方法,批量更新文章,代码如下:

from django.contrib import admin
from myapp.models import Article

def make_published(self, request, queryset):
    rows_updated = queryset.update(status=’p’)
    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)

class ArticleAdmin(admin.ModelAdmin):
    list_display = [’title’, ’status’]
    ordering = [’title’]
    actions = [make_published]

admin.site.register(Article, ArticleAdmin)

  

效果如下:

自定义动作的权限控制,重载get_actions方法,如下:(只允许名字以J大头的删除记录)

from django.contrib import admin
from myapp.models import Article

def make_published(self, request, queryset):
    rows_updated = queryset.update(status=’p’)
    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)

class ArticleAdmin(admin.ModelAdmin):
    list_display = [’title’, ’status’]
    ordering = [’title’]
    actions = [make_published]
    
    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

是不是一定要在admin.py中实现ModelAdmin的子类呢?

不一定,如果你觉得默认的ok,那么可以这样注册你的model,

admin.site.register(YourModel)

  

ModelAdmin api详解:

django (648~?)

 ModelAdmin.save_model

原始实现

如下(仅仅保存模型实例)C:\Python27\Lib\site-packages\django\contrib\admin\options.py 856~860行

    def save_model(self, request, obj, form, change):
        """
        Given a model instance save it to the database.
        """
        obj.save()

参数说明:

request - HttpRequest

obj - model.Models的子类的实例

form - ModelForm的实例

change - 布尔类型,标识是修改还是新增obj。

应用:

在obj.save之前或者之后做一些操作。

 

 ModelAdmin.delete_model

原始实现

如下(仅仅删除模型实例)C:\Python27\Lib\site-packages\django\contrib\admin\options.py 862~866行

    def delete_model(self, request, obj):
        """
        Given a model instance delete it from the database.
        """
        obj.delete()

  

参数说明:

request - HttpRequest

obj - model.Models的子类的实例

 

应用:

在obj.delete()之前或者之后做一些操作。

 

ModelAdmin.save_formset

原始实现

如下(仅仅保存formset)C:\Python27\Lib\site-packages\django\contrib\admin\options.py 868~872行

    def save_formset(self, request, form, formset, change):
        """
        Given an inline formset save it to the database.
        """
        formset.save()

  

参数说明:

request - HttpRequest

form - ModelForm的实例

formset - ModelFormSet的实例

change - 布尔类型,标识是修改还是新增obj。

应用:

在formset.save之前或者之后做一些操作。

例子:

保存之前记录操作用户

class ArticleAdmin(admin.ModelAdmin):
    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instance in instances:
            instance.user = request.user
            instance.save()
        formset.save_m2m()

 

ModelAdmin.get_ordering

原始实现

如下(仅仅保存formset)C:\Python27\Lib\site-packages\django\contrib\admin\options.py 251~255行

    def get_ordering(self, request):
        """
        Hook for specifying field ordering.
        """
        return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

参数说明:

request - HttpRequest

返回值:类似ordering属性的元组或者列表

应用:

动态排序,可根据request里面的变量进行动态排序。

 

ModelAdmin.get_search_results(request,queryset,search_term)

原始实现

    def get_search_results(self, request, queryset, search_term):
        """
        Returns a tuple containing a queryset to implement the search,
        and a boolean indicating if the results may contain duplicates.
        """
        # Apply keyword searches.
        def construct_search(field_name):
            if field_name.startswith('^'):
                return "%s__istartswith" % field_name[1:]
            elif field_name.startswith('='):
                return "%s__iexact" % field_name[1:]
            elif field_name.startswith('@'):
                return "%s__search" % field_name[1:]
            else:
                return "%s__icontains" % field_name

        use_distinct = False
        if self.search_fields and search_term:
            orm_lookups = [construct_search(str(search_field))
                           for search_field in self.search_fields]
            for bit in search_term.split():
                or_queries = [models.Q(**{orm_lookup: bit})
                              for orm_lookup in orm_lookups]
                queryset = queryset.filter(reduce(operator.or_, or_queries))
            if not use_distinct:
                for search_spec in orm_lookups:
                    if lookup_needs_distinct(self.opts, search_spec):
                        use_distinct = True
                        break

        return queryset, use_distinct

  

参数说明:

request - HttpRequest

queryset - queryset

search_term - 字符串,以空格隔开

返回值:(queryset,is_distinct)

应用:

重载以实现个性化搜索。

例子:

 实现整型数据的搜索支持

class PersonAdmin(admin.ModelAdmin):
    list_display = (’name’, ’age’)
    search_fields = (’name’,)
    def get_search_results(self, request, queryset, search_term):
        queryset, use_distinct = super(PersonAdmin, self).get_search_results(request, queryset,
        try:
            search_term_as_int = int(search_term)
        except ValueError:
            pass
        else:
            queryset |= self.model.objects.filter(age=search_term_as_int)
        return queryset, use_distinct

  

 

posted @ 2014-09-16 21:12  tommy.yu  阅读(1063)  评论(0编辑  收藏  举报