历史缘由,使用django1.6.5,shame on me....html
# 某个app下,创建admin.py 内容以下 from django.contrib.admin.models import LogEntry class LogEntry_Admin(admin.ModelAdmin): list_display = ['id', 'user', 'action_time', 'content_type', 'object_id', 'object_repr', 'change_message'] admin.site.register(LogEntry, LogEntry_Admin) # 有自动注册的库,未使用 https://github.com/Mimino666/django-admin-autoregister # 以后记录日志以下: try: LogEntry.objects.log_action( user_id=request.user.pk, content_type_id=ContentType.objects.get_for_model(FooModel).pk, object_id=None, object_repr='foo verbose_name', action_flag=0, change_message='change foo', except Exception as e: logging.error(traceback.format_exc())
# 列表中须要展现的字段 # 枚举 list_display = ['id', 'name'] # 排除 list_display = [field.name for field in MyModel._meta.fields if field.name != 'foo'] # 列表过滤器 list_filter = ['created', 'updated', 'status'] # 可搜索的字段 search_fields = ['name'] # 动做字段 actions = ['foo', 'bar'] # 只读显示字段, 通常用于添加连接 readonly_fields = ['link'] # 排序字段 ordering = ['-created'] # 查询时同时取出外建对应的model list_select_related = True # 列表每页显示多少条 list_per_page = 50
from django.utils.safestring import mark_safe from django.core.urlresolvers import reverse class Foo_Admin(admin.ModelAdmin): list_display = ['id', 'bar_link'] # 列表页中的连接字段 readonly_fields = ['foo_links'] # 编辑页中的连接字段 def bar_link(self, obj): try: # model修改页连接, admin:app名称_模型名称_change link = reverse("admin:barapp_barmodel_change", args=(bar.id,)) return mark_safe('<a href="{}" target="_blank">{}</a>'.format(link, bar.id)) except BarModel.DoesNotExist: return u'bar不存在' # 方法名后的short_description是其做为字段的描述 bar_link.short_description = u'bar连接' def foo_links(self, obj): try: links = '' foos = FooModel.objects.filter(name=obj.name) for foo in foos: link = reverse("admin:fooapp_foomodel_change", args=(foo.id,)) linkhtml = mark_safe('<a href="{}" target="_blank">{}</a>'.format(link, foo.id)) links = links + ' ' + linkhtml return links except: return None foo_links.short_description = u'foo连接' # 容许html标签 foo_links.allow_tags = True
class Foo_Admin(admin.ModelAdmin): actions = ['my_action'] def my_action(self, request, queryset): for item in queryset: PROC(item) # 把消息显示给用户 self.message_user(request, 'success' my_action.short_description = 'my wonderful action'
class ExtendedActionsMixin(object): """ 原始代码及文档地址:https://gist.github.com/rafen/eff7adae38903eee76600cff40b8b659 """ # actions that can be executed with no items selected on the admin change list. # The filtered queryset displayed to the user will be used instead extended_actions = [] def changelist_view(self, request, extra_context=None): # if a extended action is called and there's no checkbox selected, select one with # invalid id, to get an empty queryset if 'action' in request.POST and request.POST['action'] in self.extended_actions: if not request.POST.getlist(admin.ACTION_CHECKBOX_NAME): post = request.POST.copy() post.update({admin.ACTION_CHECKBOX_NAME: 0}) request._set_post(post) return super(ExtendedActionsMixin, self).changelist_view(request, extra_context) def get_changelist_instance(self, request): """ Returns a simple ChangeList view instance of the current ModelView. (It's a simple instance since we don't populate the actions and list filter as expected since those are not used by this class) """ list_display = self.get_list_display(request) list_display_links = self.get_list_display_links(request, list_display) list_filter = self.get_list_filter(request) search_fields = self.get_search_fields(request) list_select_related = self.get_list_select_related(request) ChangeList = self.get_changelist(request) return ChangeList( request, self.model, list_display, list_display_links, list_filter, self.date_hierarchy, search_fields, list_select_related, self.list_per_page, self.list_max_show_all, self.list_editable, self, ) def get_filtered_queryset(self, request): """ Returns a queryset filtered by the URLs parameters """ cl = self.get_changelist_instance(request) return cl.get_queryset(request) class Custom_ActionForm(ActionForm): """自定义admin动做参数表单 参考文档: https://github.com/cundi/blog/issues/32 """ ARGS_A = 1 ARGS_B = 2 ARGS_C = 3 CHOICES = ( (ARGS_A, u'AAA'), (ARGS_B, u'BBB'), (ARGS_C, u'CCC'), ) # 此处用到的下拉选择字段,可按需使用charfiled args = forms.ChoiceField(choices=CHOICES, label=u'命令参数') class Foo_Admin(ExtendedActionsMixin, admin.ModelAdmin): actions = ['my_action'] action_form = Custom_ActionForm extended_actions = ['my_action'] def my_action(self, request, queryset): # args为Custom_ActionForm表单中选择的项 args = int(request.POST.get('args', 0)) if args == Custom_ActionForm.ARGS_A: PROC(args)
from django.contrib import admin import datetime from django.contrib.admin import DateFieldListFilter from django.utils import timezone class CustomFilter(admin.SimpleListFilter): """自定义过滤器""" parameter_name = 'foo_status' # 做为GET请求url参数 title = u'过滤器名称' NEW, SUCCESS, FAIL = '0', '1', '2' def lookups(self, request, model_admin): return ( (self.NEW, "新建"), (self.SUCCESS, "成功"), (self.FAIL, "失败"), ) def queryset(self, request, queryset): if not self.value(): return queryset if self.value() == self.NEW: return queryset.filter(status=NEW) if self.value() == self.FAIL: return if self.value() == self.SUCCESS: return class CustomDateTimeFilter(DateFieldListFilter): """扩展admin日期过滤器,支持更多日期 参考: https://stackoverflow.com/questions/37735191/how-do-i-extend-django-admins-datefieldlistfilter-class """ def __init__(self, *args, **kwargs): super(CustomDateTimeFilter, self).__init__(*args, **kwargs) now = timezone.now() # When time zone support is enabled, convert "now" to the user's time # zone so Django's definition of "Today" matches what the user expects. if timezone.is_aware(now): now = timezone.localtime(now) today = now.date() endyear = now.year endmonth = now.month if endmonth == 1: startmonth = 12 startyear = now.year - 1 else: startmonth = now.month - 1 startyear = now.year start = datetime.datetime(startyear, startmonth, 1, 0, 0, 0, 0) # 上月1日0点 end = datetime.datetime(endyear, endmonth, 1, 0, 0, 0, 0) # 本月1日0点 self.links += (( (u'昨天', { self.lookup_kwarg_since: str(today - datetime.timedelta(days=1)), self.lookup_kwarg_until: str(today), }), (u'前天', { self.lookup_kwarg_since: str(today - datetime.timedelta(days=2)), self.lookup_kwarg_until: str(today - datetime.timedelta(days=1)), }), (u'上月', { self.lookup_kwarg_since: str(start), self.lookup_kwarg_until: str(end), }), )) class Foo_Admin(admin.ModelAdmin): list_filter = ['status', ('created', CustomDateTimeFilter), CustomFilter]
django-admin-rangefilter # 用于admin中日期范围过滤python