E
E
Eugene2017-01-29 17:56:53
Django
Eugene, 2017-01-29 17:56:53

Working with RedirectView class in Django 1.10, get_redirect_url() method not called?

There was a question about the correctness of the RedirectView class in Django 1.10.
There is a suspicion that I am doing something wrong, but I do not understand what.
Briefly about the essence of the problem.
The site implements the logic of the work of various contests.
Participants can register in several contests and publish their materials.
The user registers and automatically gets to the page of one of the contests.
If necessary, the user can go to the section of available competitions in the site menu and select another competition.
After choosing, the system remembers this choice and returns the user to the page for working with this contest.
To implement the logic, I used a ListView for the list of available contests and a RedirectView to save the selection and return to the main page.
Wrote code. The first two switching contests are performed correctly. Subsequent switches are not performed.
From the debugger, I see that the get_redirect_url() method is not called in which the contest id is remembered.
I don't understand why it stops working.
So, there is such 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'),
]

I'm running in debug mode. Registering.
[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

I get to the user's page. Everything is fine. I go to the competition selection page.
AwardMemberChooseAwardPageView.get_queryset
[29/Jan/2017 13:12:20] "GET /account/choose_award/ HTTP/1.1" 200 22897

I choose another contest - No. 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

Everything works - a page with data on the competition number 2 opens .
Again I go to the contest selection page and choose contest number 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

Everything works again. We are on the page with the data of competition No. 1 .
Again I go to the page for choosing contests, I choose contest number 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

And this is where it fails. The user enters the page with the data of the competition No. 1 .
It turns out that the transition itself is executed - but there is no call to the AwardMemberStoreAwardPageView.get_redirect_url method.
Repeated such manipulations do not change anything.
If the user logs out of the current session and re-registers, the situation repeats in the same way as described above.
Has anyone encountered something similar?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
Eugene, 2017-01-30
@beugene

As it turned out, it was necessary to correctly set the permanent attribute of the RedirectView class.
If set to False, the server sends a 302 code, and if set to True, it sends a 301 code.
The value of this attribute affects whether the browser gets data from the server or from the cache.

class AwardMemberStoreAwardPageView(RedirectView):
    permanent = False

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question