Make Django Rest Framework and Axios Work Together Nicely

This is a solution to the problem I encountered while marrying Django Rest Framework powered API and Axios JS HTTP client: Axios issues GET requests with multi-value parameters in a bit different way than Django expects.

When you create your API with Django Rest Framework, it expects multi-value GET parameters to be in form of: name=value1&name=value2

For example, you have a multiple choice field named country and in order to filter your endpoint on two countries, you need to have country parameters in url like this: country_code=PL&country_code=RU, which is quite logical.

Nowadays, Axios (https://github.com/mzabriskie/axios) is a de facto standard HTTP client for frontend apps, you use it with React, you use it with Vue, you use it everywhere, because it's simple and cool.

Let's say you want to query our API and filter it by two countries, let's try to do it with Axios, which is as simple as:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
  1. import axios from 'axios';
  2. axios.get('api/', {
  3. 'params': {'country': ['PL', 'RU']}
  4. })
  5. .then(response => {
  6. // process response.
  7. })
  8. .catch(e => {
  9. // catch errors.
  10. this.errors.push(e)
  11. })

All seems ok, we make a GET request to an /api endpoint, we pass our country codes inside params object and we expect to get a result. However, we won't get what we expect, because instead of making a query to /api?country=PL&country=RU, Axios will make a query to /api?country[]=PL&country[]=RU.

Note [] in the param names. It happens because of the way axios converts parameters into query strings, and there's not much we can do about it.

After some digging, I came to a solution to create a query string myself and not to rely on axios to do that. Luckily there's always something on NPM and our today's hero is - querystring, node's querystring module for all engines. After installing it as npm install querystring we can convert our params into a proper querystring, like so:

1
2
  1. import querystring from 'querystring';
  2. let query = querystring.stringify({'country': ['PL', 'RU']});

which as a result will produce a desired querystring: country=PL&country=RU

The last step is to modify our axios code accordingly:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  1. import axios from 'axios';
  2. import querystring from 'querystring';
  3. axios.get('api/?' + querystring.stringify({'country': ['PL', 'RU']}))
  4. .then(response => {
  5. // process response.
  6. })
  7. .catch(e => {
  8. // catch errors.
  9. this.errors.push(e)
  10. })

And the problem is solved!

Hope this helps someone. Let me know in the comments.