3

I am new to Python and Django. I did a experiment on enforcing request method (e.g. for certain url you can only use GET). Here is my code.

tests.py

from django.test import TestCase, Client
client = Client()

class MyTests(TestCase):
    def test_request_method:
        """ Sending wrong request methods should result in 405 error """
        self.assertEqual(client.post('/mytest', follow = True).status_code, 405)

urls.py

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name = 'index'),
    url(r'^mytest/', views.mytest, name = 'mytest'),
]

views.py

from django.http import HttpResponse

def mytest(request):
    if request.method == 'GET':
        return HttpResponse("Not implemented", status = 500)
    else:
        return HttpResponse("Only GET method allowed", status = 405)

But the test always returns status 500.

I saw here that this may be related to using follow=True in the client.post() call. However if I use follow=False I will get status 301 instead.

Any ideas? Thank you!

yhf8377
  • 260
  • 1
  • 2
  • 10
  • @MattiVirkkunen you are absolutely right! After removing the tailing slash i got correct status code. Thank you! (As noted I am new to this stuff...) Please post your reply as an answer. – yhf8377 Jun 23 '17 at 17:20
  • This is one of the reasons why you should prefer `reverse('mytest')` over hardcoding the url. It will always return the canonical url, so you won't encounter any redirects. – knbk Jun 23 '17 at 20:21
  • @knbk Can you please give me a short example? I don't understand what you mean by saying "reverse(my test)" – yhf8377 Jun 23 '17 at 20:41
  • Just do `from django.urls import reverse`, then instead of `'/mytest'`, you use the result of `reverse('mytest')`. `mytest` is the name you gave your url. You can read more in [Reverse resolution of URLs](https://docs.djangoproject.com/en/1.11/topics/http/urls/#reverse-resolution-of-urls). – knbk Jun 23 '17 at 21:18

1 Answers1

6

Does it perhaps redirect /mytest to /mytest/? The documentation suggests that by default, a trailing slash is added by doing a redirect if no URL pattern matches without the slash, and to quote:

Note that the redirect may cause any data submitted in a POST request to be lost.

A request caused by commonly used redirect status codes is always a GET request. You could either make the request to /mytest/ or remove the trailing slash from your URL pattern.

Matti Virkkunen
  • 63,558
  • 9
  • 127
  • 159