Testing request parameters in Django (“+” behaves differently)

32 views
Skip to first unread message

Eneko Illarramendi

unread,
Apr 18, 2015, 8:52:13 AM4/18/15
to django...@googlegroups.com
Previously posted in SO: http://stackoverflow.com/questions/29703930/testing-request-parameters-in-django-behaves-differently
-----------------------

I have a Django View that uses a query parameter to so some content filtering. Something like this:

/page/?filter=one+and+two
/page/?filter=one,or,two

I have noticed that Django converts the + to a space (request.GET.get('filter') returns one and two), and I´m OK with that. I just need to adjust the split() function I use in the View accordingly.

But...

When I try to test this View, and I call:

from django.test import Client
client = Client()
client.get('/page/', {'filter': 'one+and+two'})

request.GET.get('filter') returns one+and+two: with plus signs and no spaces. Why is this?

I would like to think that Client().get() mimics the browser behaviour, so what I would like to understand is why calling client.get('/page/', {'filter': 'one+two+three'}) is not like browsing to /page/?filter=one+and+two. For testing purposes it should be the same in my opinion, and in both cases the view should receive a consistent value for filter: be it with + or with spaces. What I don´t get is why there are two different behaviours.

Tom Evans

unread,
Apr 20, 2015, 9:30:55 AM4/20/15
to django...@googlegroups.com
On Sat, Apr 18, 2015 at 12:13 PM, Eneko Illarramendi
<eneko.ill...@gmail.com> wrote:
> Previously posted in SO:
> http://stackoverflow.com/questions/29703930/testing-request-parameters-in-django-behaves-differently
> -----------------------
>
> I have a Django View that uses a query parameter to so some content
> filtering. Something like this:
>
> /page/?filter=one+and+two
> /page/?filter=one,or,two
>
> I have noticed that Django converts the + to a space
> (request.GET.get('filter') returns one and two), and I´m OK with that. I
> just need to adjust the split() function I use in the View accordingly.

The arguments in a query string are urlencoded. Spaces are urlencoded
as '+'. Django's request.GET is a dict like object with the query
string arguments decoded.

>
> But...
>
> When I try to test this View, and I call:
>
> from django.test import Client
> client = Client()
> client.get('/page/', {'filter': 'one+and+two'})

The test client takes a dictionary of raw strings, not urlencoded
strings. If you like, you are telling it to test the URL
'/page/?filter=one%2Band%2Btwo', as '+' is urlencoded as '%2B'.

Django is consistent, the test client takes raw un-encoded strings,
and request.GET delivers raw un-encoded strings.

Cheers

Tom

Eneko Illarramendi

unread,
Apr 20, 2015, 9:57:12 AM4/20/15
to django...@googlegroups.com
Thank you Tom.

Somehow it seemed strange to test this view using client.get('/page/', {'filter': 'one and two'})
but I get why it is like this.

Cheers,
Eneko
Reply all
Reply to author
Forward
0 new messages