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)
follow-up: 3 comment:1 by , 11 years ago
comment:3 by , 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 , 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
comment:5 by , 11 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
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.
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.