Opened 2 years ago

Last modified 2 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, 2 years ago

Resolution: invalid
Status: newclosed

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, 2 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, 2 years ago

Description: modified (diff)
Resolution: invalid
Status: closednew
Summary: django.test.Client.post documentation is wrongdjango.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