如何在 django admin 的 changelist_view 中过滤查询集?
Posted
技术标签:
【中文标题】如何在 django admin 的 changelist_view 中过滤查询集?【英文标题】:How to filter queryset in changelist_view in django admin? 【发布时间】:2011-02-06 19:32:42 【问题描述】:假设我有一个网站,用户可以在其中通过管理面板添加条目。每个用户都有自己负责的类别(每个类别都有一个通过 ForeingKey/ManyToManyField 分配的编辑器)。
当用户添加条目时,我通过使用 EntryAdmin 来限制选择,如下所示:
class EntryAdmin(admin.ModelAdmin):
(...)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'category':
if request.user.is_superuser:
kwargs['queryset'] = Category.objects.all()
else:
kwargs['queryset'] = Category.objects.filter(editors=request.user)
return db_field.formfield(**kwargs)
return super(EntryAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
这样我可以限制用户可以添加条目的类别,并且效果很好。
现在棘手的部分:在条目更改列表/操作页面上,我只想显示那些属于当前用户类别的条目。我尝试使用这种方法来做到这一点:
def changelist_view(self, request, extra_context=None):
if not request.user.is_superuser:
self.queryset = self.queryset.filter(editors=request.user)
但我收到此错误:
AttributeError: 'function' 对象没有属性 'filter'
这很奇怪,因为我认为它应该是一个典型的QuerySet。基本上这样的方法是not well documented,挖掘大量的 Django 代码并不是我最喜欢的运动。
有什么想法可以实现我的目标吗?
【问题讨论】:
【参考方案1】:警告:这个答案来自 2010 年,对 Django >= 1.8 没有用。
queryset
是ModelAdmin
上的一个方法,它返回一个查询集。您需要在 EntryAdmin
类上覆盖它。
def queryset(self, request):
qs = super(EntryAdmin, self).queryset(request)
if request.user.is_superuser:
return qs
else:
return qs.filter(editors=request.user)
更改查询集将限制列表视图中显示的条目。您还需要覆盖has_change_permission
以确保用户有权在单个对象编辑页面上编辑对象。有关详细信息,请参阅 James Bennett 的以下博客文章:
http://www.b-list.org/weblog/2008/dec/24/admin/
【讨论】:
查询集需要按类别过滤。但是当用户分配了多个类别时,就会出现问题。或者也许我错过了什么。 至少在 Django 2.2 中,该方法被称为get_queryset
而不是 queryset
。
@ge0rg 是的,方法是renamed in Django 1.6。问题和答案已经有将近 10 年的历史了,所以它们对于现代版本的 Django 不是很有用。
最新 Django (3.0) 文档中的示例看起来几乎相同,除了方法名称:ModelAdmin.get_queryset。所以我猜至少那部分答案仍然有用有用吗?以上是关于如何在 django admin 的 changelist_view 中过滤查询集?的主要内容,如果未能解决你的问题,请参考以下文章
问题在 django admin 中扩展 change_form.html
Django 1.5 扩展 admin/change_form.html 对象工具
试图在 django admin 中显示/隐藏 change_list 过滤器
html Django Admin:使用AJAX保存 - 覆盖`admin / change_form.html`模板