【问题标题】:Filtering the filter: limiting choices in django admin filter by user privileges过滤过滤器:通过用户权限限制 django 管理过滤器中的选择
【发布时间】:2019-01-31 06:52:40
【问题描述】:

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

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 的东西来应用于我的过滤器选择。

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

这很难说清楚,所以我会重复一遍,希望我的冗余有一些清晰。

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

在我的经验水平上,我发现似乎可能相关的示例对我来说非常不透明。

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

【问题讨论】:

标签: django django-admin


【解决方案1】:

这是我的完整解决方案;

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)

比我想要的要复杂一些,但是如果您将其视为三个独立的小步骤,那也不算太糟糕。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 2011-03-04
    • 2013-07-26
    • 2020-09-15
    • 2015-04-30
    • 1970-01-01
    • 2015-04-03
    相关资源
    最近更新 更多