So I'm programming a site divided in sections, which are themselves divided in subsections. In my setup, when a user clicks on the link to a section (let's say for instance '/home'), they are redirected to one of its subsections (e.g. '/home/cover'). Additionally, when a user goes to the page root, they are redirected to one of the sections (in my case '/home'). With that setup, what happens when someone goes to the root, is that they are first redirected to '/home', and from there to '/home/cover'. Those redirections are implemented like this:
Main urls.py:
from django.conf.urls import patterns, include, url
from django.views.generic.base import RedirectView
urlpatterns = patterns('',
url(r'^$', RedirectView.as_view(url='/home')),
url(r'^home/', include('components.home.urls', namespace='components.home')),
...
)
components/home/urls.py:
from django.conf.urls import patterns, include, url
from django.views.generic.base import RedirectView
from components.home import views
urlpatterns = patterns('',
url(r'^$', RedirectView.as_view(url='cover')),
url(r'^cover$', views.cover, name='home_cover'),
...
)
In practice, this seems to work fine: I can navigate my site and all the redirections do what they should. However, I can't figure out how to implement my unit tests for them, and in particular for the root redirection.
The test I designed originally was like:
def test_root_url_redirects_to_home_url(self):
response = self.client.get('/')
self.assertRedirects(response, '/home', status_code=301)
However, when I run it, I'm faced with the error:
"AssertionError: 301 != 200 : Couldn't retrieve redirection page '/home':
response code was 301 (expected 200)."
Now, I could easily remove all double redirections and make every redirected URL point directly to its target, but the current configuration feels cleaner and easier to maintain, so if there is some way I can properly test it that would be perfect.
I'm very new to Django and web development in general, so I'm sorry if I'm missing an obvious answer here.
You can now perform a redirect with Django, either by using the redirect response classes HttpResponseRedirect and HttpResponsePermanentRedirect , or with the convenience function django. shortcuts.
Note − There is also a function to generate URLs; it is used in the same way as redirect; the 'reverse' method (django. core. urlresolvers. reverse). This function does not return a HttpResponseRedirect object, but simply a string containing the URL to the view compiled with any passed argument.
TestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='')
Asserts that the response return a status_code redirect status, it redirected to expected_url (including any GET data), and the final page was received with target_status_code.
If your request used the follow argument, the expected_url and target_status_code will be the url and status code for the final point of the redirect chain.
Source: Django docs
There is no harm in double redirection (aside from the extra HTTP requests). Bearing that in mind, Django's asserting also tests the redirected-to URL if it is a local URL. The default response code that it expects is 200, but as you have a double redirect, being the 301, this fails. So in order to make the test case succeed, is to assert that the redirect also redirects:
self.assertRedirects(response, '/home', status_code=301, target_status_code=301)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With