In this project i am using a different flow approach. I am not using the traditional django forms neither the django templates tags. I am using Vanilla javascript fetch for all data manipulation. All my fecth configuration are okay i have added enctype="multipart/form-data"
and {% csrf_token %}
to my form and this is my html corresponding the issue at hand:
<input style="cursor: pointer" type="file" placeholder="Aucun Fichier" id="image_upload" value="Choisir Fichier" name="image_upload" class="img_class" />
.
My problem now is that i want to upload an image file to my server. For that purpose i have the following code:
//My event listener
submit_btn.addEventListener("click", (event) => {
event.preventDefault();
const user = new Users();
user_image_upload = image_upload.value
user_image_file_field = image_file_field.files[0]
...
// My object i send to the server
post_user_info_object = {
obj_user_image_upload: user_image_upload,
obj_image_file_field: user_image_file_field,
....
}
}
When i post the form this is my image printed on the javascript console:
Next, when it reaches the server this is how it looks like (i'm posting the code first before the image):
@login_required
def edit_profile(request):
if request.user.is_authenticated:
if request.method == 'POST' or request.method == 'FILES':
data = json.loads(request.body.decode("utf-8"))
print("Data: ", data)
raw_image_file = data["obj_image_file_field"]
print('image file: ', raw_image_file)
...
And the following is the image of the console printout showing the result:
Here is the code sending to the server:
class Users {
// Sending user info to server
async postUserInfo (token, data_elements) {
const options = {
method: 'POST',
body: JSON.stringify(data_elements),
headers: {
'Content-type': 'application/json; charset-UTF-8',
'X-CSRFToken': token
}
}
let result = await fetch ('http://127.0.0.1:8000/accounts/edit-profile/', options);
let data = await result.json();
return data;
}
}
An here is my init code where i run everything:
submit_btn.addEventListener("click", (event) => {
event.preventDefault();
const user = new Users();
user_image_file_field = image_file_field.files[0]
post_user_info_object = {
obj_image_file_field: user_image_file_field
}
user.postUserInfo(csrftoken, post_user_info_object)
.then(user => {
console.log(user)
window.location.assign('http://127.0.0.1:8000/accounts/edit-profile/')
})
.catch(err => console.log(err));
})
I have visited virtually all the ressources talking about uploading images with django via fecth but all of the do so using forms and abstract this particular process i am trying to achieve
Please help me on how exactly i should get that image on the django view side, and also why it is empty on the django side while it has value on the javascript side
I have been working on a similar problem and here's how I managed to make it work.
First of all, you should not use JSON object to send files to the server. So this part won't work
body: JSON.stringify(data_elements)
There are several ways to encode an image to be able to send it to the server (like encoding it to base64) but the easiest way that I found is just to use the FormData() object
Here's a snippet of my code
let formData = new FormData()
formData.append('image', e.target.files[0])
formData.append('account', currentAccount.username)
fetch('/api/post/add', {
method: 'POST',
body: formData
}).then( response => response.json())
.then( response => {
console.log(response)
})
You can do async/await instead of promises but you get the idea.
IMPORTANT NOTE:
The content type when using FormData is 'Content-Type': 'multipart/form-data'
however, you should NOT define ANY content type in this particular request cause it will mess it up. Let the browser define the content type. Why? Read the reason here.
The backend Django part.
Again, we're not dealing with JSON so you can't use
data = json.loads(request.body.decode("utf-8"))
Here's how it should look like:
def add_image(request):
if request.user.is_authenticated:
if request.method == 'POST':
image = request.FILES.get("image")
account = request.POST.get("account")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With