尝试使用基于 class 的 django-tables2 视图按用户组过滤,无法访问 self.user

Trying to filter by user group using class based view with django-tables2, can't access self.user

我正在尝试使用基于 class 的视图,使用 django-tables2 来根据登录用户所属的组定义 table 和返回的模板。

这是我的尝试:

class cases(LoginRequiredMixin, SingleTableView):
    login_url = '/account/login/'
    if User.objects.filter(pk=self.request.user.id, groups__name='teachers').exists():
        model = Graduation
        table_class = TeachersTable
        template_name = 'mysite/teachers.html'
    elif User.objects.filter(pk=self.request.user.id, groups__name='students').exists():
        model = Graduation
        table_class = StudentsTable
        template_name = 'mysite/students.html'

认为 这种方法或多或少是正确的(我今天才了解 class 基于视图),但我不确定如何访问用户id.

这个视图的相关部分应该只在用户登录时调用(至少我认为)因为我使用的是 LoginRequiredMixin,所以 'self' 应该存在。

我看到的解决这个问题的答案是覆盖 get_queryset,但我不愿意这样做,因为我认为这会破坏 django-tables2.

在这种情况下,执行我想要执行的操作的最佳方法是什么?

这里发生了一些事情。

首先,加载模块时 class 运行 中的所有代码,而不是视图 运行 时的代码。所以你的代码 运行ning 在错误的时间。部分原因是,您无权访问 self.

self 不是那么神奇,它不会凭空出现,你只能在 class 方法中使用它:

class Foo:
    self.spam = "eggs"  # Wrong, no self here.

class Bar:
    def set_spam(self):  # self is the instance of the class.
        self.spam = "eggs"  # Works.

我不确定 table_class 是什么,从搜索来看它似乎来自 django-tables,所以这里有一些猜测。看起来你想要这样的东西:

class GraduationCaseView(LoginRequiredMixin, SingleTableView):
    model = Graduation
    
    def get_template_names(self):
        if self.request.user.groups.filter(name='teachers').exists():
            return ['mysite/teachers.html']
        return 'mysite/students.html'

    def get_table_class(self):
        if self.request.user.groups.filter(name='teachers').exists():
            return TeachersTable
        return StudentsTable

这应该有效。这有一个问题:您将两次执行相同的数据库查询。有一些方法可以解决这个问题,但它需要了解一些 CBV 及其执行顺序。由于我不确定 SingleTableView 在做什么,这可能有效也可能无效:

class GraduationCaseView(LoginRequiredMixin, SingleTableView):
    model = Graduation
    
    def get_queryset(self):
        qs = super().get_queryset()
        if self.request.user.groups.filter(name='teachers').exists():
            self.group = 'teachers'
        else:
            self.group = 'students'
        return qs
    
    def get_template_names(self):
        if self.group == 'teachers':
            return ['mysite/teachers.html']
        return 'mysite/students.html'

    def get_table_class(self):
        if self.group == 'teachers':
            return TeachersTable
        return StudentsTable

您可能也应该阅读 Python's documentation of classes,以便了解它们的工作原理。

还有一点,如果设置了 settings.LOGIN_URL,则无需在视图中设置 login_url