django-ninja
django-ninja copied to clipboard
Bad request
When I send a post of only text values, it works. The same when I send only a image file. But I´m getting this error when I send a mix of both: POST http://127.0.0.1:8000/api/towns 400 (Bad Request)
o {message: 'Request failed with status code 400', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
code: "ERR_BAD_REQUEST"
config:
adapter: Æ’ (e)
data: FormData {}
env: {FormData: null}
headers: {Accept: 'application/json, text/plain, */*'}
maxBodyLength: -1
maxContentLength: -1
method: "post"
timeout: 0
transformRequest: [Æ’]
transformResponse: [Æ’]
transitional: {silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false}
url: "http://127.0.0.1:8000/api/towns"
validateStatus: Æ’ (e)
xsrfCookieName: "XSRF-TOKEN"
xsrfHeaderName: "X-XSRF-TOKEN"
[[Prototype]]: Object
message: "Request failed with status code 400"
name: "AxiosError"
request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
response:
config:
adapter: Æ’ (e)
data: FormData {}
env: {FormData: null}
headers: {Accept: 'application/json, text/plain, */*'}
maxBodyLength: -1
maxContentLength: -1
method: "post"
timeout: 0
transformRequest: [Æ’]
transformResponse: [Æ’]
transitional: {silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false}
url: "http://127.0.0.1:8000/api/towns"
validateStatus: Æ’ (e)
xsrfCookieName: "XSRF-TOKEN"
xsrfHeaderName: "X-XSRF-TOKEN"
[[Prototype]]: Object
data: {detail: "Cannot parse request body ('utf-8' codec can't decode byte 0xff in position 285: invalid start byte)"}
headers: {content-length: '114', content-type: 'application/json; charset=utf-8', cross-origin-opener-policy: 'same-origin', date: 'Tue, 16 Aug 2022 07:50:01 GMT', referrer-policy: 'same-origin', …}
request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status: 400
statusText: "Bad Request"
[[Prototype]]: Object
[[Prototype]]: Error
constructor: Æ’ o(e,t,n,r,o)
toJSON: Æ’ ()
isAxiosError: true
[[Prototype]]: Object
Maybe it´s because of how I build the FormData? This is my code. HTML & JS:
townForm.addEventListener("submit", (event) => {
event.preventDefault();
let values = document.querySelectorAll('#town-form .data');
postImages(values, "towns");
});
function postImages(values, url) {
console.log(`inputFile-> `, inputFile.files[0]);
const image = inputFile.files[0];
let object = {};
let valuesArray = Array.prototype.map.call(values, function (element) {
return element;
});
for (element in valuesArray) {
if (valuesArray[element].value === "true") {
object[valuesArray[element].id] = true;
} else if (valuesArray[element].value === "false") {
object[valuesArray[element].id] = false;
} else if (valuesArray[element].id === "youtube_video_code") {
object[valuesArray[element].id] = youtube_parser(valuesArray[element].value);
} else {
object[valuesArray[element].id] = valuesArray[element].value;
}
}
console.log(`object-> `, object);
const data = JSON.stringify(object);
console.log(`data-> `, data);
formData.append("data", data);
formData.append("image", image);
console.log(`formData-> `, formData);
let requestURL = 'http://127.0.0.1:8000/api/' + url;
axios.post(requestURL, formData)
.then(function (response) {
console.log(response);
$('#success-toast').toast('show');
})
.catch(function (error) {
console.log(error);
$('#error-toast').toast('show');
});
}
MODEL:
class Town(models.Model):
name = models.CharField(max_length=255)
slug = models.CharField(max_length=255)
description = models.TextField()
image = models.ImageField(upload_to=GenericImageUploadTo('image'), null=True)
thumbnail = models.ImageField(upload_to=GenericImageUploadTo('thumbnail'), null=True)
youtube_video_code = models.CharField(max_length=255)
web = models.CharField(max_length=255)
map_link = models.CharField(max_length=255)
lat = models.IntegerField(null=True)
long = models.IntegerField(null=True)
map_pct_x = models.IntegerField(null=True)
map_pct_y = models.IntegerField(null=True)
activated = models.BooleanField(default=False)
def __str__(self):
return self.name
API URLS:
@api.post("/towns")
def create_town(request, payload: TownSchema):
obj = Town.objects.create(**payload.dict())
return {"id": obj.id}
from what I see the response from the serve is
"Cannot parse request body ('utf-8' codec can't decode byte 0xff in position 285: invalid start byte)
which probably means that request body is not good... so yeah something with building your formData (BTW it's not even clear where you initialize the formData variable in your code)
I'm going to take a good look at the FormData building. I initialized it beforehand like this: const formData = new FormData();
Thank you very much for answering so quickly