kert
kert

Reputation: 2271

RedirectView and url reverse with optional args

Short: i'm trying to do a simple redirect view to a third party app provided named url, with optional parameters

Third party view url ( from provider.oauth2 package ) is registered like this

url('^authorize/?$',login_required(Capture.as_view()), name='capture'),

I've imported this urlconf in namespace='oauth2' In my view this works fine:

class RedirectToCapture(RedirectView):
    pattern_name = 'oauth2:capture'

    def get_redirect_url(self, *args, **kwargs):
        return super(RedirectToCapture,self).get_redirect_url(*args,**kwargs)

This will fail to reverse() url because there are no optional parameters defined in the urlpattern above

class RedirectToCapture(RedirectView):
    pattern_name = 'oauth2:capture'

    def get_redirect_url(self, *args, **kwargs):
        kwargs['response_type'] = 'code'
        return super(RedirectToCapture,self).get_redirect_url(*args,**kwargs)

This hack works

class RedirectToCapture(RedirectView):
    pattern_name = 'oauth2:capture'
    query_string = True

    def get_redirect_url(self, *args, **kwargs):
        self.request.META['QUERY_STRING'] = urlencode({'response_type' :'code')
        return super(RedirectToCapture,self).get_redirect_url(*args,**kwargs)

This is super ugly. Another way, doing reverse() myself and omitting pattern_name

class RedirectToCapture(RedirectView):
    def get_redirect_url(self, *args, **kwargs):
        self.url = reverse('oauth2:capture') + '?' + urlencode({'response_type' :'code' })
        return super(RedirectToCapture,self).get_redirect_url(*args,**kwargs)

Is this the cleanest way ? Touching either args or kwargs in any way causes reverse() to stop matching

PS: And yes i want to use a class based view here derived from RedirectView for multiple unrelated reasons. I know i can simply do http.HttpResponseRedirect(url)

Upvotes: 1

Views: 1831

Answers (1)

meshy
meshy

Reputation: 9076

You're very nearly there. In your final version you can just to return the url instead of calling super.

class RedirectToCapture(RedirectView):
    def get_redirect_url(self, *args, **kwargs):
        get_args = urlencode({'response_type' :'code' })
        return reverse('oauth2:capture') + '?' + get_args

Upvotes: 3

Related Questions