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