#33757 closed Cleanup/optimization (fixed)
Clarify django.test.Client.post() file upload example
Reported by: | bastian-wattro | Owned by: | Tim Graham |
---|---|---|---|
Component: | Documentation | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Following https://docs.djangoproject.com/en/4.0/topics/testing/tools/#django.test.Client.post
with Django version 4.0.4 to write my first unit tests, I failed to upload a file under a given keyword *with the *name* / *attachment* pattern*
As described there, I tried to set *name* and *file pointer* like this:
Submitting files is a special case. To POST a file, you need only provide the file field name as a key, and a file handle to the file you wish to upload as a value. For example:
with open('mal.csv', 'rb') as fp:
self.client.post('/post/endpoint/', {'name': 'fred', 'attachment': fp})
}}}
The name *attachment* here is not relevant; use whatever name your file-processing code expects.
This made me assume that the file given via the filepointer will be accessible via the keyword fred
.
This [test](https://github.com/django/django/blob/d5bc36203057627f6f7d0c6dc97b31adde6f4313/tests/file_uploads/tests.py#L86-L93) works because the [endpoint being called](https://github.com/django/django/blob/d5bc36203057627f6f7d0c6dc97b31adde6f4313/tests/file_uploads/views.py#L18) (contrary to what I would expect) checks the keyword of the file pointer (fiel_field
in this case) and the name
separately.
What I wanted was
with open('mal.csv', 'rb') as fp: self.client.post('/post/endpoint/', {'fred': fp})
as (contraty to what is written in the docs) name is not required
Sorry for the confusion and thanks for the quick responses.
Change History (9)
comment:1 by , 3 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 3 years ago
The example in the documentation initializes a client c = Client()
while the snippet here uses self.client
. It might that the latter version has some state attached to it (like a login) which makes the difference, but it's impossible to debug without some minimal example code. Please include that in future reports (and first confirm a bug in Django using support channels).
comment:3 by , 3 years ago
Description: | modified (diff) |
---|---|
Resolution: | invalid |
Status: | closed → new |
Summary: | django.test.Client.post documentation is wrong → django.test.Client.post documentation is confusing |
Sorry for the confusion and thanks for the quick responses. I'll try to clarify:
Following the docs
with Django version 4.0.4 to write my first unit tests, I failed to upload a file under a given keyword with the name / attachment pattern
The docs state:
>>> c = Client() >>> with open('wishlist.doc', 'rb') as fp: ... c.post('/customers/wishes/', {'name': 'fred', 'attachment': fp})
The name *attachment* here is not relevant; use whatever name your file-processing code expects.
This made me assume that the file given via the file pointer will be accessible via the keyword fred
.
This test works because the endpoint being called (contrary to what I would expect) checks the keyword of the file pointer (fiel_field
in this case) and the name
separately.
Reading the docs for a third time now I get the meaning.
What I don't understand is why the keyword 'name' is there, and why doesn't it simply say something like:
To submit a file, provide a file handle to the file you wish to upload as a value. For example:
>>> c = Client() >>> with open('wishlist.doc', 'rb') as fp: ... c.post('/customers/wishes/', {'wishes_file': fp})
will be accessible via request.FILES['wishes_file']
Again thanks for your time. I get now that this is something that probably only confuses new comers like my self.
comment:4 by , 3 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
I don't see anything confusing in this docs.
This made me assume that the file given via the file pointer will be accessible via the keyword
fred
.
Docs explicitly states that the name attachment
here is not relevant. fred
is not a keyword but a value for the name
and it's used that way in other examples.
What I don't understand is why the keyword 'name' is there, and why doesn't it simply say something like:
IMO it's valuable to show that other fields are handled properly and you don't need to send files separately.
comment:5 by , 3 years ago
Docs explicitly states that the name attachment here is not relevant.
See that is what confuses me. attachment
is very relevant, as it is the keyword in the FILES dict.
This is implicitly stated ("use whatever name your file-processing code expects") but not clear if you jump in the docs without context information.
comment:6 by , 3 years ago
Has patch: | set |
---|---|
Resolution: | invalid |
Status: | closed → new |
Summary: | django.test.Client.post documentation is confusing → Clarify django.test.Client.post() file upload example |
Type: | Bug → Cleanup/optimization |
Version: | 4.0 → dev |
I offer a PR.
comment:7 by , 3 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Ready for checkin |
Thanks for the report, however it works for me, see also tests.
This snippet is exactly the same as the version you think is not working 🤔
If you're having trouble understanding how Django works, see TicketClosingReasons/UseSupportChannels for ways to get help.