Make ✨ 🍰 ✨ requests act like jQuery when passing nested objects to data/payload

Requests does not support dict with depth greater than 1 on parameter data for a x-www-form-urlencoded based request.

What I'm proposing here is to remove depth from a dict while keeping actual sent data untouched.

## Expected Result

```python
print(response.request.body)
# auth_user=test&auth_pwd=test&json_data%5Boperation%5D=core%2Fget&json_data%5Bclass%5D=ServiceChange&json_data%5Bkey%5D=SELECT+ServiceChange+WHERE+id%3D429&json_data%5Boutput_fields%5D=request_state&json_data%5Bh%5D%5Bt%5D=1
```

PHP/jQuery $.params support this syntax out of the box. As requests is not about supporting the way PHP/jQuery $.params work internally, this PR maybe doomed.

## Actual Result

What happened instead.

```python
print(response.request.body)
# auth_user=test&auth_pwd=test&json_data=operation&json_data=class&json_data=key&json_data=output_fields&json_data=h
```

Remote server only see json_data = h and that is actually wrong.

## Reproduction Steps

```python
from requests import post
from pprint import pprint

if __name__ == '__main__':

    response = post(
        'https://api.ipify.org?format=json',
        {
            'auth_user': 'test',
            'auth_pwd': 'test',
            'json_data': {
                'operation': 'core/get',
                'class': 'ServiceChange',
                'key': 'SELECT ServiceChange WHERE id=429',
                'output_fields': 'request_state',
                'h': {
                    't': 1
                }
            }
        }
    )

    pprint(
        response.request.body
    )

```

```python
from requests.models import RequestEncodingMixin

my_dict_ = {
    'json_data': {
        'operation': 'get',
        'class': 'ServiceChange',
        'key': 'SELECT ServiceChange',
        'output_fields': 'request_state',
        'h': {
            't': 1
        }
    },
    'auth': 'blabla',
}


if __name__ == '__main__':

    print(
        RequestEncodingMixin._encode_params(my_dict_)
    )

    # Without change
    # urlencoded; json_data=operation&json_data=class&json_data=key&json_data=output_fields&json_data=h&auth=blabla

    # With change
    # urlencoded; auth=blabla&json_data%5Boperation%5D=get&json_data%5Bclass%5D=ServiceChange&json_data%5Bkey%5D=SELECT+ServiceChange&json_data%5Boutput_fields%5D=request_state&json_data%5Bh%5D%5Bt%5D=1
    # urldecoded; auth=blabla&json_data[operation]=get&json_data[class]=ServiceChange&json_data[key]=SELECT ServiceChange&json_data[output_fields]=request_state&json_data[h][t]=1
```

Not sure if `to_key_val_list` should call `to_flat_dict`. 

Will most certainly need modifications but the idea is here. Waiting for review. Will rebase/squash commit later. 

Be to clear, there is no spec on uri that mention arrays. RFC3986 does not speak of it.

[Is array syntax using square brackets in URL query strings valid?](https://stackoverflow.com/questions/11490326/is-array-syntax-using-square-brackets-in-url-query-strings-valid)
[What RFC defines arrays transmitted over HTTP?](https://stackoverflow.com/questions/15854017/what-rfc-defines-arrays-transmitted-over-http)



More info about this, jQuery seems to use this array-like syntax on uri. https://api.jquery.com/jQuery.param/

```javascript
// >=1.4:
$.param({ a: { b: 1, c: 2 }, d: [ 3, 4, { e: 5 } ] });
// "a[b]=1&a[c]=2&d[]=3&d[]=4&d[2][e]=5"
```

Also, this ? `&d[]=3&d[]=4`, Passing list to uri param.

As a non-reviewer: This seems like something application specific, not a feature-set that would live within the HTTP client.

Agreed. But something should happen when passing nested dict. This behavior is wrong. We loss data between passing and sending. At least raise a warning or whatnot. 
Maybe the good way is to propose the same as https://github.com/vuejs/vue-router/issues/1259
And ship request with a jquery like uri string generator.

And for the record, this impl does not interfere with previous simple usages. 

This PR is now ready for review.

For summary :

```py
r = requests.get(httpbin('get'), params={'test': ['foo', 'baz']})
# will no longer output
# old render : get?test=foo&test=baz
# new render : get?test[]=foo&test[]=baz
```

With this we embrace the way jQuery encode nested objects/arrays.

Why should we merge ?

  - [x] `requests` is on a higher level than urllib, this does not make sense in `urllib`, but can in `requests`
  - [x] PHP and Ruby on Rails support this syntax out of the box, and is used by more than 30 % of the remote backends.
  - [x] This PR would make it more beginner friendly, advanced users that are looking for `test=foo&test=baz` are more likely to encode their payload manually. Not the other way around.
  - [x] This change does not break or change actual behavior expect for the multivalued param case which is a very rare case in my opinion. 

@nateprewitt 

Related issues : 

  - #1641
  - #3902
  - #864


<p align="center">
<img src="https://user-images.githubusercontent.com/9326700/73437904-756f6980-434d-11ea-9d07-8dfc435d9799.gif" alt="Well, I don't think pfs/request is looking to change. I tried at least. Byebye :)"/>
</p>


@Ousret My thoughts on this PR haven't changed, this seems like application-specific behavior, not a feature that would be a part of the HTTP client library.

Thank you for the answer.

This is also handled by an external library: https://toolbelt.readthedocs.io/en/latest/formdata.html

Closing per above comment, please use toolbelt for this functionality.