django - 如何访问 django admin.SimpleListFilter 中过滤后的查询集

标签 django django-admin

假设我们有两个对象:

class Author(models.Model):
    name = models.CharField(length=50)

class Book(models.Model):
    author = models.ForeignKey(Author)
    is_bestseller = models.BooleanField()

在 BookAdmin 中,如果我们指定

list_filter = ('author', 'is_bestseller')

为您提供的“作者”选择将始终是数据库中的所有作者,无论他们是否写过畅销书。

我希望我的过滤器的选择受到当前选择的限制。我尝试使用 admin.SimpleListFilter 以一般方式执行此操作, 然而,我被困住了,因为:

model_admin.get_queryset()

返回未过滤的查询集(即所有对象,而不仅仅是当前被用户过滤掉的对象)。

如何获取 BookAdmin 的过滤查询集?

编辑:为了更好地说明问题,这是我的代码:

class ForeignFieldFilter(admin.SimpleListFilter):
    field = None

    def lookups(self, request, model_admin):
        queryset = model_admin.get_queryset(request).select_related(self.field)
        # ^^^ !!! Returns UNFILTERED queryset - it's not affected by other filters

        field_ids = queryset.values_list(self.field, flat=True)

        for field_value in self.model..objects.filter(id__in=field_ids):
            yield (field_value.pk, str(field_value))

    def queryset(self, request, queryset):
        value = self.value()

        # Check that any value was passed, if not, return unmodified queryset
        if not value:
            return queryset

        return queryset.filter({'{0}__pk'.format(self.field): value})


def foreign_field_filter_factory(field, model, title=None):
    title = title or (field[:1].upper() + field[1:])
    return type(
        "ForeignFieldFilter_{0}".format(field),
        (ForeignFieldFilter,),
        {
            'field': field,
            'title': title,
            'parameter_name': field,
            'model': model
        })

最佳答案

对于图书管理

class AuthorBestSeller(admin.SimpleListFilter):
    title = 'Best selling authors'
    parameter_name = 'bestseller'

    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(author_id=self.value())
        else:
            return queryset

    def lookups(self, request, model_admin):
        qs = model_admin.get_queryset(request)
        query_attrs = dict([(param, val) for param, val in request.GET.items()])
        qs = qs.filter(**query_attrs)
        for book in qs.filter(is_bestseller=1):  # or might be able to use yeild here
            ret.append((book.author_id, book.author))
        return ret

编辑:嗯...这也不太有效。它只会为您提供畅销书作者的列表。

然后添加到 BookAdmin

list_filter = (AuthorBestSeller, )

关于django - 如何访问 django admin.SimpleListFilter 中过滤后的查询集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28257979/

相关文章:

python - 如何使用 Django Admin 注册自定义表单

django - 一个应用有多个模型 vs. 多个应用只有一个模型

python - Django:如何以编程方式更改用户的 super 用户和/或员工状态

python - "global name ' _ ' is not defined"在提高 ValidationError 期间

Django admin list_display 换行符

django - 无法使用 django-mptt 在 django admin 中创建多对多对象

python - 从 Django 自定义管理页面创建的用户无法登录

Python - 在 1and1 主机上安装 Pillow 和 MySQL-python

python - 如何在 Django 中扩展到 'base.html' 模板样式

python - 缩略图现在显示在 django 管理 ListView 中