歷史緣由,使用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