Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing request parameters in Django ("+" behaves differently)

Tags:

python

django

I have a Django View that uses a query parameter to do 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+and+two'}) 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.

like image 694
eillarra Avatar asked Apr 17 '15 15:04

eillarra


People also ask

How does Django do testing?

The preferred way to write tests in Django is using the unittest module built-in to the Python standard library. This is covered in detail in the Writing and running tests document. You can also use any other Python test framework; Django provides an API and tools for that kind of integration.

How do I get parameters in GET request Django?

We can access the query params from the request in Django from the GET attribute of the request. To get the first or only value in a parameter simply use the get() method. To get the list of all values in a parameter use getlist() method.

What is RequestFactory in Django?

The request factory The API for the RequestFactory is a slightly restricted subset of the test client API: It only has access to the HTTP methods get() , post() , put() , delete() , head() , options() , and trace() . These methods accept all the same arguments except for follow .

What are request parameters?

Request parameters are used to send additional information to the server. A URL contains these parameters. There are two types of parameters: Query Parameter: These are appended to the end of the request URL, Query parameters are appended to the end of the request URL, following '?'


1 Answers

The plusses in a query string are the normal and correct encoding for spaces. This is a historical artifact; the form value encoding for URLs differs ever so slightly from encoding other elements in the URL.

Django is responsible for decoding the query string back to key-value pairs; that decoding includes decoding the URL percent encoding, where a + is decoded to a space.

When using the test client, you pass in unencoded data, so you'd use:

client.get('/page/', {'filter': 'one and two'})

This is then encoded to a query string for you, and subsequently decoded again when you try and access the parameters.

like image 189
Martijn Pieters Avatar answered Oct 12 '22 15:10

Martijn Pieters