Opened 11 years ago

Closed 11 years ago

#20574 closed Bug (worksforme)

Django Client Put Method Data is not Send

Reported by: edwinlunando Owned by: nobody
Component: Testing framework Version: 1.5
Severity: Normal Keywords: Test, Client, Put, Data
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I want to test my REST API like this:

data = {
            'access_token': access_token.token
        }
response = self.client.put(reverse('api:update_user'), data)

The question is, how can I access my data or query string at request object from my view? request.POST, request.GET, request.body, and request.META QUERY_STRING is empty. After I looked into the client put code like this.

    def put(self, path, data='', content_type='application/octet-stream',
            **extra):
        "Construct a PUT request."
        return self.generic('PUT', path, data, content_type, **extra)

    def generic(self, method, path,
                data='', content_type='application/octet-stream', **extra):
        parsed = urlparse(path)
        data = force_bytes(data, settings.DEFAULT_CHARSET)
        r = {
            'PATH_INFO':      self._get_path(parsed),
            'QUERY_STRING':   force_str(parsed[4]),
            'REQUEST_METHOD': str(method),
        }
        if data:
            r.update({
                'CONTENT_LENGTH': len(data),
                'CONTENT_TYPE':   str(content_type),
                'wsgi.input':     FakePayload(data),
            })
        r.update(extra)
        return self.request(**r)

The data parameter is not added to query string like get method like.

    def get(self, path, data={}, **extra):
        "Construct a GET request."

        parsed = urlparse(path)
        r = {
            'CONTENT_TYPE':    str('text/html; charset=utf-8'),
            'PATH_INFO':       self._get_path(parsed),
            'QUERY_STRING':    urlencode(data, doseq=True) or force_str(parsed[4]),
            'REQUEST_METHOD':  str('GET'),
        }
        r.update(extra)
        return self.request(**r)

So, I think the PUT and DELETE method should behave the same like GET and POST method at client. The "'QUERY_STRING': urlencode(data, doseq=True) or force_str(parsed[4])," should be used at PUT and DELETE method.

Change History (5)

comment:1 by Aymeric Augustin, 11 years ago

urlencode(data, doseq=True) emulates HTML form submission in a browser, which only makes sense for GET and POST since browsers only support these two methods.

comment:2 by edwinlunando, 11 years ago

Hmm. So, there is no possible way to access the data parameter?

in reply to:  1 comment:3 by edwinlunando, 11 years ago

Replying to aaugustin:

urlencode(data, doseq=True) emulates HTML form submission in a browser, which only makes sense for GET and POST since browsers only support these two methods.

Then, how can I use the put method to test my application? The put seems not doing anything if I cannot access the data.

comment:4 by merb, 11 years ago

you could access the data with request.body, but it isn't parsed.
https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.body

Version 0, edited 11 years ago by merb (next)

comment:5 by Anton Baklanov, 11 years ago

Resolution: worksforme
Status: newclosed

Hi edwinlunando.

data = {
            'access_token': access_token.token
       }
response = self.client.put(reverse('api:update_user'), data)

In this case you should be able to find your data in request.body.

Please note that PUT and DELETE methods are not designed to transmit data within query string, so setting it to urlencode(data, doseq=True) for all requests will be not correct (but if you want it for some reason - you can urlencode your data when building url for request, e.g. self.client.put(reverse('api:update_user')+'?'+urlencode(data, doseq=True))).

Also, here is kind of related ticket - #12635.

I'm closing this ticket as worksforme, but feel free to reopen if request.body is really empty and you think that it is because of some django's bug.

Note: See TracTickets for help on using tickets.
Back to Top