在Django Admin中过滤过滤器

1 投票
2 回答
2503 浏览
提问于 2025-04-16 12:08

这是我为学校项目写的代码,链接在这里:http://dpaste.com/434311/

这段代码运行得很好,在学生管理列表页面,我能看到课程的筛选功能,这样挺好的。不过,正如你所看到的,我的项目是多租户的,所以在筛选区域,我想只显示当前用户所在学校的课程(通过会话来跟踪用户),但现在我看到的是所有学校的课程列表。

所以我想把这一行

list_filter   = ['xclass']  

替换成类似这样的内容

list_filter   = Class.objects.filter(school=request.session['school_id'])

我该怎么做呢?

2 个回答

1

我遇到这个问题很多次了。不幸的是,你需要写一个自定义的、没有文档说明的 FilterSpec

在Django 1.3或更早版本的Django管理后台中自定义过滤器

这个问题正在处理,所以很快就会有解决方案...
http://code.djangoproject.com/ticket/5833


另外一个办法是修改列表页面的基础 queryset,只显示你学校ID对应的数据。 http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.queryset

def queryset(self, request):
    qs = super(MyModelAdmin, self).queryset(request)
    return qs.filter(xclass__school__id=request.session['school_id'])
2

从2012年3月23日发布的1.4版本开始,你可以使用官方的 django.contrib.admin.SimpleListFilter

下面是一个示例代码,用于只列出活跃公司的过滤器:

class ActiveCompaniesFilter(SimpleListFilter):
    # Human-readable title which will be displayed in the
    # right admin sidebar just above the filter options.
    title = _('active companies')

    # Parameter for the filter that will be used in the URL query.
    parameter_name = 'project__company'

    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.
        """
        lookup_list = Company.objects.active().values_list('id', 'name').distinct()
        # 'objects.active' is a custom Company manager and is 
        # equivalent to filter 'objects.filter(status=100)'  
        return lookup_list

    def queryset(self, request, queryset):
        """
        Returns the filtered queryset based on the value
        provided in the query string and retrievable via
        `self.value()`.
        """
        # Compare the requested value (either '80s' or 'other')
        # to decide how to filter the queryset.
        if self.value():
            return queryset.filter(project__company=self.value())

撰写回答