尝试使用基于 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
。
我正在尝试使用基于 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
。