简体   繁体   中英

Using curl to post data to django 1.9 form

I am using django 1.9.

I have a form that uses the following fields:

class UploadFileForm(forms.Form):
    component = forms.ChoiceField(choices=[(int(x.id), x.name) for x in Component.objects.all()])
    title = forms.CharField(max_length=200)
    notes = forms.CharField(max_length=2000, widget=forms.Textarea(attrs={'rows': 5}))
    file = forms.FileField()

I can use the form perfectly when I access it from a browser.

But when I try to use curl to fill the form, I keep getting error " This field is required "

<ul class="errorlist"><li>This field is required.</li></ul>
<p><label for="id_title">Title:</label> <input id="id_title" maxlength="200" name="title" type="text" /></p>
<ul class="errorlist"><li>This field is required.</li></ul>
<p><label for="id_notes">Notes:</label> <textarea cols="40" id="id_notes" maxlength="2000" name="notes" rows="5">
</textarea></p>
<ul class="errorlist"><li>This field is required.</li></ul>
<p><label for="id_file">File:</label> <input id="id_file" name="file" type="file" /></p>
        <button type="submit"> upload file</button>

My csrdmiddlewaretoken is being accepted properly as I am able to see that in the response output.

Here are the different curl requests I tried:

`curl <url> \
-X POST -H "Content-Type: application/json" \
-H "Accept: text/html,application/json" \
-H "X-CSRFToken: <token grabbed from form page source>" \
-H "Cookie: csrftoken=<token grabbed from form page source>" \
 -d 'title=testCurl'`

`curl <url> \
-X POST -H "Content-Type: application/json" \
-H "Accept: text/html,application/json" \
-H "X-CSRFToken: <token grabbed from form page source>" \
-H "Cookie: csrftoken=<token grabbed from form page source>" \
 -F 'title=testCurl'`

`curl <url> \
-X POST -H "Content-Type: application/json" \
-H "Accept: text/html,application/json" \
-H "X-CSRFToken: <token grabbed from form page source>" \
-H "Cookie: csrftoken=<token grabbed from form page source>" \
 -d '{"title":"testCurl"}'`

Once this works, I need to find a way to pass a file in the file field.

Can anyone help me out with this?

----- Edits: Based on suggestion from @ohrstrom:

I see the following when I do 'copy as curl' from chrome developer tools.

curl 'http://localhost:8000/releases/binary_upload' -H 'Cookie: JSESSIONID=84666B9EE0BB747F04AC3179FEB78F65; csrftoken=E50JjoNz1qigYUehGdxPjnsscCNaFslu' -H 'Origin: http://localhost:8000' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryn3n6mrAf19RXCh3A' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Cache-Control: max-age=0' -H 'Referer: http://localhost:8000/releases/binary_upload' -H 'Connection: keep-alive' -H 'DNT: 1' --data-binary $'------WebKitFormBoundaryn3n6mrAf19RXCh3A\r\nContent-Disposition: form-data; name="csrfmiddlewaretoken"\r\n\r\nE50JjoNz1qigYUehGdxPjnsscCNaFslu\r\n------WebKitFormBoundaryn3n6mrAf19RXCh3A\r\nContent-Disposition: form-data; name="component"\r\n\r\n13\r\n------WebKitFormBoundaryn3n6mrAf19RXCh3A\r\nContent-Disposition: form-data; name="title"\r\n\r\ntest1\r\n------WebKitFormBoundaryn3n6mrAf19RXCh3A\r\nContent-Disposition: form-data; name="notes"\r\n\r\ntest123\r\n------WebKitFormBoundaryn3n6mrAf19RXCh3A\r\nContent-Disposition: form-data; name="file"; filename="Topology_Components.png"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundaryn3n6mrAf19RXCh3A--\r\n' --compressed

But when I execute the same command from terminal, it says 'The submitted file is empty'

========Final Edit======== Found a solution. Adding it to answers below.

If you need more implementation details, you can find it at https://github.com/kiran-vemuri/DevServe

Form fields in Django are required by default:

https://docs.djangoproject.com/en/1.9/ref/forms/fields/#required

You are only sending the 'title' field in your data, and that is the only field not giving an error.

Either send all the form fields in the data that you are sending, or make the fields required=False.

class UploadFileForm(forms.Form):
    component = forms.ChoiceField(required=False, choices=[(int(x.id), x.name) for x in Component.objects.all()])
    title = forms.CharField(max_length=200)
    notes = forms.CharField(required=False, max_length=2000, widget=forms.Textarea(attrs={'rows': 5}))
    file = forms.FileField(required=False)

Instead of directly sending a POST request to a web form. I am currently implementing django-restframework .

With viewsets for all type of HTTP requests, I added some extra file processing and now I can use the following REST call to send data using curl.

`
curl -H "Content-Disposition: attachment;" \
-X POST \
-F "name=test_file" \ 
-F "component_id=14" \
-F "notes=Hello World how are you.." \
-F "file=@<path-to-file>" http://localhost:8000/rest/binaries/
`

I used to pass only Data and its values so i used this much only:

curl http://127.0.0.1:8000/api/ \
-H "Accept: application/json" \
-d '{"name":"testcurl","ph":"123456789"}'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM