过滤过滤器:通过用户权限限制 django 管理员过滤器中的选择



好的,所以我现在可以限制更改表单中可用的选项,如下所示:

def formfield_for_foreignkey(self, db_field, request, **kwargs):
from login.models import Room
groups = [group.name for group in request.user.groups.all()]
if 'principal' in groups:
schoolname = request.user.principal.school.name
if db_field.name == 'room':
print("match")
kwargs['queryset'] = Room.objects.filter(school__name=schoolname)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
list_display = ('surname','givennames', 'room')
list_filter = ('room',)

也就是说,上述内容成功地向用户仅显示在其学校注册的学生。

我的麻烦是用户仍然在list_filter上看到他们未连接到的学校的房间,这忽略了formfield_for_foreignkey

因此,下拉菜单没有将六个教室视为过滤器上的选择,而是显示了该地区所有学校的数百间教室。我试图找到一个同样简单的答案,但没有任何答案。我想要的是将类似formfield_for_foreignkey的东西应用于我的过滤器选择。

我想过滤过滤器的选项!难怪谷歌没有帮助!

这很难清楚地表达出来,所以我会重复一遍,希望我的冗余有一些清晰度。

我正在尝试过滤可供用户过滤的选项,仅过滤用户具有写入权限的选项。我想要一些学校校长可以过滤学生名单的房间选择;相反,我得到了很多,其中大多数都不适用,因为该主体在那里没有读取或写入权限。

我发现似乎可能相关的例子在我的经验水平上对我来说是相当不透明的。

有什么简单的食谱吗?谢谢!

这是我的完整解决方案;

class StudentAdmin(admin.ModelAdmin):
def get_queryset(self,request):
# if principal (not district user) only show students
# whose classroom is in principal's school
qs = super(StudentAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
else:
groups = [group.name for group in request.user.groups.all()]
if 'principal' in groups:
school = request.user.principal.school
return qs.filter(room__school=school)
else:
return qs
def formfield_for_foreignkey(self, db_field, request, **kwargs):
# if principal (not district administrator) 
# limit transfer to within principal's school
from login.models import Room
groups = [group.name for group in request.user.groups.all()]
if 'principal' in groups:
schoolname = request.user.principal.school.name
print(db_field)
print(type(db_field))
if db_field.name == 'room':
print("match")
kwargs['queryset'] = Room.objects.filter(school__name=schoolname)
return super().formfield_for_foreignkey(db_field, request, **kwargs)

class CustomRoom(admin.SimpleListFilter):
# if principal (not district user)
# only offer filter to classrooms in principal's school  
title = 'Classroom'
parameter_name = 'classroom'
def lookups(self,request,model_admin):
from login.models import Room,School
groups = [group.name for group in request.user.groups.all()]
if 'principal' in groups:
school = request.user.principal.school
rooms = Room.objects.filter(school=school)
return ((room.id,room.roomno) for room in rooms)
else:
rooms = Room.objects.all()
return ((room.id,room.roomno) for room in rooms)
def queryset(self,request,queryset):
selected = self.value()
# WAS return queryset.filter(room=selected)
# this does not handle All case correctly 
if selected:
return queryset.filter(room=selected)
else:
return queryset

list_display = ('surname','givennames', 'room')
list_filter=('enrolled',CustomRoom,)
# Register the admin class with the associated model
admin.site.register(Student, StudentAdmin)

比我想要的要混乱得多,但如果你把它看作是三个独立的小步骤,那就不太可怕了。

最新更新