При попытке фильтрации по группе пользователей с использованием представления на основе классов с django-tables2 не удается получить доступ к self.user
Я пытаюсь использовать представление на основе классов с использованием django-tables2 для определения таблицы и шаблона, возвращаемого в зависимости от того, к какой группе принадлежит зарегистрированный пользователь.
Это моя попытка сделать это:
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'
Я думаю, что подход более или менее правильный (я только сегодня узнал о представлениях на основе классов), но я не уверен, как получить доступ к идентификатору пользователя.
Соответствующие части этого представления должны вызываться только тогда, когда пользователь вошел в систему (по крайней мере, я думаю), потому что я использую LoginRequiredMixin, поэтому должно существовать "я".
В ответах, которые я видел при решении этой проблемы, говорится, что переопределить get_queryset, но я не хочу этого делать, поскольку думаю, что это сломает django-tables2.
Как лучше всего в этом случае делать то, что я пытаюсь сделать?
1 ответ
Здесь происходит несколько вещей.
Во-первых, весь код в классе выполняется при загрузке модуля, а не при запуске представления. Значит, ваш код запущен не в то время. Частично из-за этого у вас нет доступа кself
.
self
это не волшебство, оно не появляется ниоткуда, вы можете использовать его только в методах класса:
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, чтобы понять, как они работают.
Еще одна вещь, вам не нужно устанавливать login_url
на ваш взгляд, если settings.LOGIN_URL
установлен.