Opened 4 years ago

Last modified 4 years ago

#33757 closed Cleanup/optimization

django.test.Client.post documentation is confusing — at Version 3

Reported by: bastian-wattro Owned by: nobody
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 bastian-wattro)

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 (3)

comment:1 by Mariusz Felisiak, 4 years ago

Resolution: → invalid
Status: new → closed

Thanks for the report, however it works for me, see also ​tests.

What worked was the (way more intuitive) ...

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.

comment:2 by Tim Graham, 4 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 bastian-wattro, 4 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.

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