django admin查看、过滤和搜索

1 ModelAdmin能作什么

ModelAdmin是admin应用中最经常使用的一个类,最终效果都将在这个类中体现出来。总的来讲,这个类能够完成如下功能:html

逻辑实现python

单个对象(object)的操做:建立(add)、修改(change)、删除(delete)数据库

结果集(queryset)的操做:查看(display)、搜索(search)、过滤(filter)、分页(paginator)、排序(sort)django

权限控制:增删改查、自定义权限app

界面布局ide

每一个modelAdmin有四个页面,添加页面(add)、修改页面(change)、列表页面(changelist)、历史页面(history),每一个页面含有本身特定的区域,称之为block。自定义各个block的内容和位置。函数

2 ModelAdmin基本准则

# 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)等信息,这对于自定义相关选项是有很是大的帮助。

3 数据查看

列显示

list_display和get_list_display(self,request)返回是一个tuple或list,若是子类须要进行修改请使用list。每一个元素都是一个字符串,按优先级高低排列以下:

  1. 模型字段:在model定义的XxxField字段

  2. 函数:原型def get_filed_name(obj)

  3. ModelAdmin方法:原型def get_filed_name(self,obj)

  4. 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方法获得默认结果集在进行过滤,固然仍是一次性访问数据库的。

4 数据过滤

在数据表格的右上角显示为一个过滤工具条,如图。每一个过滤值以一个连接形式展示。

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 选项控制,它将在表头显示一个“年-月-日”过滤器。

5 数据搜索

http://stackoverflow.com/questions/2106084/search-fields-in-django-python


参考 http://my.oschina.net/u/995588/blog/220276

相关文章
相关标签/搜索