Python “Django”;列表“U过滤器”;基于管理查询集
我正在开发一个既有管理员又有副管理员的应用程序。子管理员是根据其所属的组创建的。因此,副管理员只能查看与其组相关的数据。此功能工作正常 现在,我想创建一个基于用户的过滤器选项。对于超级管理员,它可以正常工作,但是当我从sub-admin查看时,我可以在过滤器列表中看到完整的用户列表。如何根据子管理员用户限制此列表 假设总共有20个用户,而sub admin在他的组中只有3个用户。因此,我只能在列表视图中看到3个,但在过滤器选项中,我可以看到所有20个。我可以将此筛选器仅限于这3个用户吗 我的管理模型如下所示:Python “Django”;列表“U过滤器”;基于管理查询集,python,django,Python,Django,我正在开发一个既有管理员又有副管理员的应用程序。子管理员是根据其所属的组创建的。因此,副管理员只能查看与其组相关的数据。此功能工作正常 现在,我想创建一个基于用户的过滤器选项。对于超级管理员,它可以正常工作,但是当我从sub-admin查看时,我可以在过滤器列表中看到完整的用户列表。如何根据子管理员用户限制此列表 假设总共有20个用户,而sub admin在他的组中只有3个用户。因此,我只能在列表视图中看到3个,但在过滤器选项中,我可以看到所有20个。我可以将此筛选器仅限于这3个用户吗 我的管理
class VideoDetailsAdmin(admin.ModelAdmin):
list_display = ('video_id', 'user', 'status', 'description', 'video_name', 'upload_time', 'duration')
list_filter = ('user', )
def get_queryset(self, request):
# Get the groups of logged in user
query_set = Group.objects.filter(user = request.user)
group_list = []
for g in query_set:
group_list.append(g.name)
# Get the user ids of Users in those groups
id_list = []
for user in list(User.objects.filter(groups__name__in=group_list)):
id_list.append(user.id)
# Create unique users list
users = list(set(id_list))
# Override the get_queryset method for Admin
qs = super(VideoDetailsAdmin, self).get_queryset(request)
if not request.user.is_superuser:
return qs.filter(user__in = users)
else:
return qs
我在Django上看到的资源很少,但我想知道解决这个问题的最佳方法是什么。有没有办法重复使用get_queryset()代码
Django版本:2.1
编辑1:
class UserFilterList(SimpleListFilter):
title = "user"
parameter_name = "user"
def lookups(self, request, model_admin):
visible_users = model_admin.get_visible_users(request)
print(visible_users[0])
return ((user, user) for user in visible_users)
def queryset(self, request, queryset):
return self.value()
class UserFilterList(SimpleListFilter):
title = "user"
parameter_name = "user"
def lookups(self, request, model_admin):
if not request.user.is_superuser:
visible_users = model_admin.get_visible_users(request)
# Sub user - return same group users
return ((user.id, user) for user in visible_users)
else:
# Superuser - return all users
return ((user.id, user) for user in User.objects.filter())
def queryset(self, request, queryset):
return queryset.filter(user=self.value()) if self.value() else queryset
class VideoDetailsAdmin(admin.ModelAdmin):
list_display = ('video_id', 'user', 'status', 'description', 'video_name', 'upload_time', 'duration')
list_filter = (UserFilterList, )
def get_visible_users(self, request):
# Get the groups of logged in user
query_set = Group.objects.filter(user = request.user)
group_list = []
for g in query_set:
group_list.append(g.name)
return User.objects.filter(groups__name__in=group_list)
def get_queryset(self, request):
users = self.get_visible_users(request)
# Override the get_queryset method for Admin
qs = super(VideoDetailsAdmin, self).get_queryset(request)
if not request.user.is_superuser:
return qs.filter(user__in = users)
else:
return qs
进行了以下修改,但没有可见的过滤器
# Filter list
class UserFilterList(admin.SimpleListFilter):
# Human readable title, which is displayed on the right sidebar
title = ("User")
# Parameter for the filter that will be used in the URL query
parameter_name = "user"
def lookups(self, request, model_admin):
# To get user's groups
query_set = Group.objects.filter(user = request.user)
group_list = []
for g in query_set:
group_list.append(g.name)
# To get all users associated in those groups
id_list = []
for user in list(User.objects.filter(groups__name__in=group_list)):
id_list.append(user.id)
users = list(set(id_list))
qs = model_admin.get_queryset(request)
def queryset(self, request, queryset):
if not request.user.is_superuser:
return qs.filter(user__in = users)
else:
return qs
编辑2:
class UserFilterList(SimpleListFilter):
title = "user"
parameter_name = "user"
def lookups(self, request, model_admin):
visible_users = model_admin.get_visible_users(request)
print(visible_users[0])
return ((user, user) for user in visible_users)
def queryset(self, request, queryset):
return self.value()
class UserFilterList(SimpleListFilter):
title = "user"
parameter_name = "user"
def lookups(self, request, model_admin):
if not request.user.is_superuser:
visible_users = model_admin.get_visible_users(request)
# Sub user - return same group users
return ((user.id, user) for user in visible_users)
else:
# Superuser - return all users
return ((user.id, user) for user in User.objects.filter())
def queryset(self, request, queryset):
return queryset.filter(user=self.value()) if self.value() else queryset
class VideoDetailsAdmin(admin.ModelAdmin):
list_display = ('video_id', 'user', 'status', 'description', 'video_name', 'upload_time', 'duration')
list_filter = (UserFilterList, )
def get_visible_users(self, request):
# Get the groups of logged in user
query_set = Group.objects.filter(user = request.user)
group_list = []
for g in query_set:
group_list.append(g.name)
return User.objects.filter(groups__name__in=group_list)
def get_queryset(self, request):
users = self.get_visible_users(request)
# Override the get_queryset method for Admin
qs = super(VideoDetailsAdmin, self).get_queryset(request)
if not request.user.is_superuser:
return qs.filter(user__in = users)
else:
return qs
最终工作解决方案(感谢@dirkgroten):
class UserFilterList(SimpleListFilter):
title = "user"
parameter_name = "user"
def lookups(self, request, model_admin):
visible_users = model_admin.get_visible_users(request)
print(visible_users[0])
return ((user, user) for user in visible_users)
def queryset(self, request, queryset):
return self.value()
class UserFilterList(SimpleListFilter):
title = "user"
parameter_name = "user"
def lookups(self, request, model_admin):
if not request.user.is_superuser:
visible_users = model_admin.get_visible_users(request)
# Sub user - return same group users
return ((user.id, user) for user in visible_users)
else:
# Superuser - return all users
return ((user.id, user) for user in User.objects.filter())
def queryset(self, request, queryset):
return queryset.filter(user=self.value()) if self.value() else queryset
class VideoDetailsAdmin(admin.ModelAdmin):
list_display = ('video_id', 'user', 'status', 'description', 'video_name', 'upload_time', 'duration')
list_filter = (UserFilterList, )
def get_visible_users(self, request):
# Get the groups of logged in user
query_set = Group.objects.filter(user = request.user)
group_list = []
for g in query_set:
group_list.append(g.name)
return User.objects.filter(groups__name__in=group_list)
def get_queryset(self, request):
users = self.get_visible_users(request)
# Override the get_queryset method for Admin
qs = super(VideoDetailsAdmin, self).get_queryset(request)
if not request.user.is_superuser:
return qs.filter(user__in = users)
else:
return qs
不要更改您的
VideoDetailsAdmin
,只使用自定义列表筛选器:
class VideoDetailsAdmin(ModelAdmin):
list_filter = UserFilterList # that's the only line to change
def get_visible_users(self, request): # small refactor to re-use in filter
query_set = Group.objects.filter(user=request.user)
group_list = []
for g in query_set:
group_list.append(g.name)
# To get all users associated in those groups
return User.objects.filter(groups__name__in=group_list)
def get_queryset(self, request):
users = self.get_visible_users(request)
# Override the get_queryset method for Admin
qs = super(VideoDetailsAdmin, self).get_queryset(request)
if not request.user.is_superuser:
return qs.filter(user__in=users)
else:
return qs
class UserFilterList(SimpleListFilter):
def lookups(self, request, model_admin):
visible_users = model_admin.get_visible_users(request)
return ((user.pk, user.username) for user in visible_users)
def queryset(self, request, queryset):
return queryset.filter(user_id=self.value()) if self.value() else queryset
如链接到的文档所示,您需要通过子类化
SimpleListFilter
来创建自己的列表过滤器。这两种方法都是非常自我解释的,只是根据用户是管理员还是副管理员,将不同的列表返回到lookups
。尤其是更下面的绿色音符应该会有帮助。所以你应该先试试,如果你被卡住了,请寻求帮助。你打算如何区分这三个用户?基于普通组。我已经在上面提到的代码中实现了这一点piece@dirkgroten下面是我对代码的理解-它将基于定制的过滤器获得结果,在这种情况下是80年代,90年代等等,但我实际上在寻找的是限制边栏本身的元素,django应该使用它的逻辑来检索结果。假设管理员在侧边栏中有20个用户,我希望sub-Admin只看到3个用户。这3个用户将根据用户与此子管理员的组相似性来确定。否,lookups()
将返回列表筛选器中显示的选项。因此,您应该返回要显示的3个用户。它们是元组(值,显示),在您的例子中是(id
,name
)。然后,queryset()
是基于所选值返回的查询,但在您的情况下,它只是默认值,因此您可能不需要覆盖它。我需要做一些修改,例如添加def queryset(),否则它是不允许的。虽然我正在寻找用户名,但现在我可以看到用户id,但当我点击它时,什么都没有发生。请选中EDIT 2 Now it链接正在工作,但默认情况下,它不显示任何内容,如果我单击“全部”,它将不显示任何内容。虽然当我单击单个用户ID时它工作正常,但是我在元组中输入的值可能是错误的方式,或者发布了错误的类型。检查浏览器源代码以查看链接中的值,并在def queryset()
内设置断点以检查self.value()
是什么。是的,self.value()为空表示“全部”。默认self.value()为无,但当我选择单个元素时,它是那些元素(如44、26等)的值。