Code

Opened 3 years ago

Closed 2 years ago

#14611 closed New feature (wontfix)

django.test.Client is missing post *and* get possibility

Reported by: Ciantic Owned by: nobody
Component: Testing framework Version: 1.2
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: yes
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have a view that takes GET and POST parameters, currently there exists django.test.Client.post() and Client.get() but they don't provide means to test this combination cleanly.

As an example solution I suggest to implement Client.request() also which would take POST and GET parameters, e.g.

c = Client()

c.request(reverse('my-view-name'), 
          get={'getvar' : 'value'}, 
          post={'postvar' : 'value'}, ...)

Currently workaround is to fake this using the post method like this:

c = Client()

c.post(reverse('my-test-view') + '?' + django.utils.http.urlencode({'getvar' : 'value'}), 
       {'postvar' : 'value'}, ...)

Which as said, is not very clean.

Attachments (0)

Change History (5)

comment:1 Changed 3 years ago by dmoisset

  • Needs documentation unset
  • Needs tests unset
  • Owner changed from nobody to dmoisset
  • Patch needs improvement unset

comment:2 Changed 3 years ago by dmoisset

  • Needs documentation set
  • Needs tests set
  • Owner changed from dmoisset to nobody
  • Triage Stage changed from Unreviewed to Accepted

I dislike the TestClient.request method, because it hides which actual HTTP method is used. The only way to do an HTTP POST should be TestClient.post to avoid ambiguity.

However I think that this would work pretty well:

c = Client()
c.post(reverse('my-view-name'), 
       getdata={'getvar' : 'value'}, 
       data={'postvar' : 'value'}, ...)

i.e., adding a getdata kwarg to the post method. This is useful and doesn't break compatibility, and we still keep a single obvious way to do POST requests.

comment:3 Changed 3 years ago by Ciantic

Yes you are totally right.

Though I suggest for backwards compatibility to put the getdata as at least third kwarg, if not last, since people probably use the Client.post without specifying the kwarg name, like:

c = Client()
c.post(reverse('my-view-name'], {'postvar': 'value'}, ...)

comment:4 Changed 3 years ago by julien

  • Severity set to Normal
  • Type set to New feature

comment:5 Changed 2 years ago by aaugustin

  • Easy pickings unset
  • Resolution set to wontfix
  • Status changed from new to closed
  • UI/UX unset

To be honest, the title of this ticket doesn't make much sense given how HTTP works. There are two orthogonal mechanisms involved here:

  • 1) HTTP methods
    • Client.get performs a GET request;
    • Client.post performs a POST request.
  • 2) HTML forms
    • when submitted with a GET, form data is encoded in the query string, and Django exposes it in request.GET;
    • when submitted with a POST, it's in the request body, and Django exposes it in request.POST.

The data argument of the test client is designed to hold simulated form data, and is automatically inserted in requests according to these rules.


That said, it's absolutely legal to use query string parameters in the URL of a POST request. But that isn't be form data. Adding an argument called get_data would be extremely confusing.

In addition, I'm not eager to add a query_string_parameters argument to the test client, because Django favors clean URL design. I'm also afraid of possible confusions with form data in GET requests.

So, for all these reasons, I'm going to reject this ticket. The recommended solution is to use self.client.post('/my/url/?param=value', form_data).

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.