ModelAdmin是admin應用中最經常使用的一個類,最終效果都將在這個類中體現出來。總的來講,這個類能夠完成如下功能:html
邏輯實現python
單個對象(object)的操做:建立(add)、修改(change)、刪除(delete)數據庫
結果集(queryset)的操做:查看(display)、搜索(search)、過濾(filter)、分頁(paginator)、排序(sort)django
權限控制:增刪改查、自定義權限app
界面佈局ide
每一個modelAdmin有四個頁面,添加頁面(add)、修改頁面(change)、列表頁面(changelist)、歷史頁面(history),每一個頁面含有本身特定的區域,稱之爲block。自定義各個block的內容和位置。函數
# admin應用和普通Django同樣,也有本身的urls模塊、views模塊、template前臺模板,記住它們的規則是很是必要的。工具
# 每一個model只能擁有一個ModelAdmin與之關聯,這個model也能夠是一個代理model,具體參見proxy modeloop
#admin.site.register是將ModelAdmin和Model關聯,此後在ModelAdmin中方法中obj參數都是指這裏的model對象。佈局
# ModelAdmin對於同一個選項一般有成員變量定義和方法定義,且後者具備更高的優先級。在下面的例子裏remark列不會顯示。
#coding=utf8 from django.contrib import admin class StudentModelAdmin(admin.Model): list_display = ['name','sex','remark'] def get_list_display(self, request): return ['name','sex']
# 基本上每一個選項的方法中都含有一個request參數,表明了本次請求對象,含有當前登陸用戶(request.user),請求參數(request.POST或request.GET)等信息,這對於自定義相關選項是有很是大的幫助。
list_display和get_list_display(self,request)返回是一個tuple或list,若是子類須要進行修改請使用list。每一個元素都是一個字符串,按優先級高低排列以下:
模型字段:在model定義的XxxField字段
函數:原型def get_filed_name(obj)
ModelAdmin方法:原型def get_filed_name(self,obj)
model方法:def get_filed_name(self)
最常使用的是1和2。第二種方法除了能夠顯示字符串以外,還能夠顯示html文本,好比一個連接、一張圖片等,需設置allow_tags=True。下面是一個完整的例子,顯示當前帳戶的餘額狀態。
from django.contrib import admin class PayAccount(models.Model): customer = models.OneToOneField(Customer, verbose_name=u'客戶') balance = models.FloatField(verbose_name=u'餘額(元)', default=0) remark = models.CharField(max_length=200, verbose_name='備註', null=True, blank=True) def __unicode__(self): return self.customer.name class Meta: verbose_name = u'預繳帳戶' verbose_name_plural = u'預繳帳戶' #admin.py class PayAccountModelAdmin(CustomizeModelAdmin): def get_account_state(self, obj): if obj.balance < 0: return u'<span style="color:red;font-weight:bold">%s</span>' % (u"已欠費",) elif obj.balance <= 50: return u'<span style="color:orange;font-weight:bold">%s</span>' % (u"餘額不足",) else: return u'<span style="color:green;font-weight:bold">%s</span>' % (u"正常",) get_account_state.short_description = u'帳戶狀態' get_account_state.allow_tags = True list_display = ['customer', 'balance', 'get_account_state', 'remark']
效果如圖
def queryset(self,request)(django1.6如下)或def get_queryset(self,request)(django1.6+)
返回一個queryset對象,經常使用的作法是先調用父類的queryset方法獲得默認結果集在進行過濾,固然仍是一次性訪問數據庫的。
在數據表格的右上角顯示爲一個過濾工具條,如圖。每一個過濾值以一個連接形式展示。
list_filter是描述可過濾的列的集合,返回的是一個tuple或list。其中的每一個元素能夠是如下的類型。
字段名稱:這個字段能夠是BooleanField, CharField, DateField, DateTimeField, IntegerField, ForeignKey 和ManyToManyField,不過若是可能值太多的話,仍是考慮用搜索的方法,否則過濾工具條會拖得很長。
一個繼承自admin.SimpleListFilter的類,它主要有如下幾個重要的屬性和方法:
title:就是過濾條上「以」後面的文字。
def lookups(self,request,modeladmin):返回一個nX2的二維列表,每一個元素表明一個過濾值,前面是查詢變量值,後面是顯示在工具條的文字。
paramter_name:查詢變量名
def queryset(self,request,queryset):返回結果集,在處理GET參數時已經複製給self.value()中了,所以這個函數的實現方式一般是 對self.value()進行判斷,返回相應的結果集,不過注意一點的是self.value()是字符型,若是你的lookup是整數型的須要轉化類型。
下面的這個例子實現了帳戶餘額狀態過濾。
功能需求:狀態分爲三種:當餘額大於50元時,爲正常狀態;當餘額在0-50元(含0和50)時,爲餘額不足狀態;當餘額小於0時,爲已欠費狀態。由於數據存的是餘額這個字段,狀態過濾須要自定過濾器。
class AccountBalanceStateFilter(admin.SimpleListFilter): title = (u'餘額狀態') # Parameter for the filter that will be used in the URL query. parameter_name = 'balance_state' def lookups(self, request, model_admin): """ Returns a list of tuples. The first element in each tuple is the coded value for the option that will appear in the URL query. The second element is the human-readable name for the option that will appear in the right sidebar. """ return ( (0, u'正常'), (1, u'餘額不足'), (2, u'已欠費'), ) def queryset(self, request, queryset): """ Returns the filtered queryset based on the value provided in the query string and retrievable via `self.value()`. """ if self.value(): if int(self.value()) == 0: return queryset.filter(balance__gt=50) if int(self.value()) == 1: return queryset.filter(balance__range=(0, 50)) if int(self.value()) == 2: return queryset.filter(balance__lt=0)
效果見上圖。其中「已欠費」的連接GET字符串就含有:?balance_state=2。「所有」過濾值是admin自動添加的,它的鏈接就沒有balance_state這個查詢變量了。
另外,admin對於時間的過濾處理可使用上面的形式即在list_filter添加一個datetime類型的字段,還能夠用date_hierarchy 選項控制,它將在表頭顯示一個「年-月-日」過濾器。
http://stackoverflow.com/questions/2106084/search-fields-in-django-python