Возник вопрос в корректности работы класса RedirectView в Django 1.10.
Есть подозрение, что я делаю что то неправильно, но что - не понимаю.
Коротко о сути задачи.
Сайт реализует логику работы различных конкурсов.
Участники могут зарегистрироваться в нескольких конкурсах и публиковать свои материалы.
Пользователь регистрируется и автоматически попадает на страницу одного из конкурсов.
Если нужно пользователю, в меню сайта можно перейти в раздел доступных конкурсов и выбрать другой конкурс.
После выбора, система запоминает этот выбор и возвращает пользователя на страницу работы с этим конкурсом.
Для реализации логики использовал ListView для списка доступных конкурсов и RedirectView для сохранения выбора и возврата на основную страницу.
Написал код. Первые два переключения конкурсов выполняются корректно. Последующие переключения не выполняются.
Из отладчика вижу, что не вызывается метод get_redirect_url() в котором запоминается id конкурса.
Не понимаю почему перестаёт работать.
Итак, есть такой views.py:
## views.py
# только выдержка используемых классов в данной задаче
class AwardContextMixin(ContextMixin):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Основной конкурс
# Если пользователь ранее выбрал конкурс то выбираем этот конкурс
if self.request.user.is_authenticated():
user = self.request.user
profile_user = get_object_or_404(ProfileUser, user=user)
if profile_user is not None:
award_id = self.request.session.get('chosen_award', None)
if award_id is None:
award = Award.get_active_award()
context['award'] = award
self.request.session['chosen_award'] = award.id
else:
award = Award.objects.get(pk=award_id)
context['award'] = award
else:
context['award'] = Award.get_active_award()
return context
class AwardMemberChooseAwardPageView(ListView, AwardContextMixin):
template_name = 'choose_award_list.html'
model = AwardProfileUser
def get_queryset(self):
print('AwardMemberChooseAwardPageView.get_queryset')
qs = None
if self.request.user.is_authenticated():
user = self.request.user
profile_user = get_object_or_404(ProfileUser, user=user)
if profile_user is not None:
qs = AwardProfileUser.objects.filter(
profile_user=profile_user,
is_agree_with_terms=True,
award__is_active=True
)
return qs
class AwardMemberStoreAwardPageView(RedirectView):
permanent = True
query_string = False
pattern_name = 'awards:private_room'
# url = '/account/private_room/'
def get_redirect_url(self, *args, **kwargs):
print('AwardMemberStoreAwardPageView.get_redirect_url')
# без этого возникает ошибка 410
self.url = reverse(self.pattern_name)
# берем значение параметра из url
award_id = kwargs.get('award_id', None)
if award_id is not None:
# запоминаем в сессии
self.request.session['chosen_award'] = award_id
return super().get_redirect_url(*args, **kwargs)
class AwardPrivateRoomPageView(TemplateView, AwardContextMixin):
template_name = 'private_room.html'
def get_context_data(self, **kwargs):
print('AwardPrivateRoomPageView.get_context_data')
context = super().get_context_data(**kwargs)
# Далее готовим данные для шаблона
# ...
return context
## urls.py
urlpatterns = [
url(r'account/private_room/$', AwardPrivateRoomPageView.as_view(), name='private_room'),
url(r'account/choose_award/$', AwardMemberChooseAwardPageView.as_view(), name='choose_award'),
url(r'account/choose_award/(?P<award_id>[0-9]+)/$', AwardMemberStoreAwardPageView.as_view(), name='store_award'),
]
Запускаю в режиме отладки. Регистрируюсь.
[29/Jan/2017 13:11:40] "GET /login/ HTTP/1.1" 200 18302
[29/Jan/2017 13:11:42] "POST /login/ HTTP/1.1" 302 0
AwardPrivateRoomPageView.get_context_data
[29/Jan/2017 13:11:43] "GET /account/private_room/ HTTP/1.1" 200 48343
Попадаю на страницу пользователя. Все нормально. Перехожу на страницу выбора конкурсов.
AwardMemberChooseAwardPageView.get_queryset
[29/Jan/2017 13:12:20] "GET /account/choose_award/ HTTP/1.1" 200 22897
Выбираю другой конкурс -
№2
AwardMemberStoreAwardPageView.get_redirect_url
[29/Jan/2017 13:12:55] "GET /account/choose_award/2/ HTTP/1.1" 301 0
AwardPrivateRoomPageView.get_context_data
[29/Jan/2017 13:12:55] "GET /account/private_room/ HTTP/1.1" 200 36569
Все работает - открывается страница с данными по конкурсу
№2.
Опять перехожу на страницу выбора конкурсов и выбираю конкурс
№1.
AwardMemberChooseAwardPageView.get_queryset
[29/Jan/2017 13:13:08] "GET /account/choose_award/ HTTP/1.1" 200 22807
AwardMemberStoreAwardPageView.get_redirect_url
[29/Jan/2017 13:13:11] "GET /account/choose_award/1/ HTTP/1.1" 301 0
AwardPrivateRoomPageView.get_context_data
[29/Jan/2017 13:13:11] "GET /account/private_room/ HTTP/1.1" 200 47794
Опять все работает. Мы на странице с данными конкурса
№1.
Снова перехожу на страницу выбора конкурсов, выбираю конкурс
№2.
AwardMemberChooseAwardPageView.get_queryset
[29/Jan/2017 13:13:23] "GET /account/choose_award/ HTTP/1.1" 200 22897
AwardPrivateRoomPageView.get_context_data
[29/Jan/2017 13:13:38] "GET /account/private_room/ HTTP/1.1" 200 47794
И вот тут происходит сбой. Пользователь попадает на страницу с данными конкурса
№1.
Получается, сам переход выполняется - но нет вызова метода AwardMemberStoreAwardPageView.get_redirect_url .
Повторные подобные манипуляции ничего не меняют.
Если пользователь выйдет из текущей сессии и заново зарегистрируется - ситуация повторяется аналогично описанному выше.
Кто-то с подобным сталкивался?