I am working on a Django website for the nonprofit. I am on the profile images part. I am trying to upload images using the image as a button to submit. I have the file chooser that opens. Then, it submits upon finishing choosing a file. It should be saving the image uploaded to the Django database. So far, my AJAX request to the Django view, its success function works correctly. However, when I try to print to the terminal my test, nothing is printed in the python terminal. Also, the image doesn’t update appropriately.
# sourcetemplatesprofile-pageschild-profile.html
...
<script>
$(document).ready(function () {
if (typeof jQuery == 'undefined') {
console.error('jQuery is not loaded!');
} else {
console.log('jquery is loaded');
}
// Get the image and input elements
var imageButton = document.getElementById("image-button");
var fileInput = document.getElementById("file-input");
// Add a click event listener to the image element
imageButton.addEventListener("click", function (e) {
// Simulate a click on the hidden input element
e.preventDefault();
fileInput.click();
});
// Add a change event listener to the input element
fileInput.addEventListener("change", function (e) {
e.preventDefault();
// Get the selected file from the input element
var file = fileInput.files[0];
console.log(file);
console.log(typeof file);
// Create a URL for the file object
if (
!(
file.type == "image/jpeg" ||
file.type == "image/jpg" ||
file.type == "image/png"
)
){
alert("Image must be jpeg, jpg or png");
$("#fileInput").val("");
return False;
}
var formData = new FormData();
formData.append("newPic", file);
// Update the image source with the file URL
// imageButton.src = url;
$('#submitBtn').submit(submitF(e, formData));
});
function submitF(e, pic) {
e.preventDefault();
// if (!$("#fileInput").val()) {
// alert("Please choose a file");
// }
// var formData = new FormData(this);
console.log("form data. #picform submitted");
$.ajax({
headers: {
'X-CSRFToken': $("input[name=csrfmiddlewaretoken]").val(),
},
url: "{% url 'users:profile' %}",
// url: "/profile",
data: {
newPic: pic,
csrfmiddlewaretoken: $("input[name=csrfmiddlewaretoken]").val(),
},
method: "POST",
contentType: false, // Set contentType and processData to false for file uploads
processData: false,
success: function (data) {
alert("success ");
},
error: function (xhr, status, error) {
console.log("AJAX error: ", status, error);
},
});
// $("#imageButton").attr("src", formData);
}
});
</script>
...
{% load crispy_forms_tags %}
<div id="profile-row" class="row g-3">
<div id="profile-img-container" class="col-md-5">
<form id="picForm" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input
id="file-input"
type="file"
name="picture"
accept="image/*"
style="display: none"
/>
{% if request.user.profile_pic.url %}
<img
id="image-button"
src="{{ request.user.profile_pic.url }}"
style="
width: 100px;
height: 100px;
border: 1px solid black;
cursor: pointer;
"
/>
{% elif request.user.profile_pic.url == None %}
<img src="{% static '/profile-images/default.png' %}" />
<p>Test</p>
{% endif %}
<button type="submit" id="submitBtn" value="Submit">Submit</button>
</form>
</div>
...
# usersviews.py
...
@login_required
def profile(request):
user = get_object_or_404(afbUsers)
if request.method == 'POST':
new_pic_file = request.FILES.get('newPic')
if new_pic_file:
print('testing 123', new_pic_file.name)
# Update the logic based on your model and how you want to handle the file
user.profile_pic = new_pic_file
user.save()
messages.success(request, 'Profile image update success!')
return JsonResponse({'status': 'success'})
else:
messages.error(request, 'No file uploaded.')
return JsonResponse({'status': 'error', 'message': 'No file uploaded.'})
context = {'user': user}
return render(request, 'profile-pages/child-profile.html', context)
...
2
Answers
Had to have a separate view to return JsonResponse and render.
Are you sure that you get correct object via this query:
You don’t pass any ID or anything. The request may be valid but your code raises 404 here anyway and it returns 404 to the AJAX code.