简体   繁体   中英

Image upload with fetch api not working in django

My views.py file

def change_profile_picture(request):
    if not request.user.is_authenticated:
        return JsonResponse({"status": "403", "msg": "Unauthorized request"})
    if request.method == 'POST':
        if request.is_ajax():
            form = UploadPictureForm(request.POST)
            if form.is_valid():
                customuser = request.user.customuser
                customuser.picture = form.cleaned_data['picture']
                customuser.save()
                return JsonResponse(
                    {
                        "status": "200",
                        "msg": "Successful",
                        "data": f"{customuser.picture.url}"
                    }
                )
            else:
                return JsonResponse({"status": "400", "msg": "invalid form"})
        else:
            return JsonResponse({"status": "401", "msg": "Bad request"})
    else:
        return JsonResponse({"status": "403", "msg": "invalid request method"})

forms.py

class UploadPictureForm(forms.Form):
    picture = forms.ImageField(
        label="Profile picture"
    )

Javascript code:

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

$('.upload-btn').on('click', () => {
    document.getElementById('id_picture').click();
})
$('.close-btn').on('click', () => {
    document.getElementById('profile-picture').src = $('#profile-picture').data('target');
    document.getElementById('submit-picture').style.visibility = 'hidden';
})
$('#submit-picture').on('click', () => {
    var picture = document.querySelector('input[type="file"]');
    var formData = new FormData();
    formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
    formData.append('picture', picture.files[0]);
    fetch('/auth/change-profile-picture/', {
        method: 'POST',
        body: formData,
        cache: 'default',
        mode: 'cors',
        credentials: 'include',
        headers: {
            "X-Requested-With": "XMLHttpRequest",
        }
    })
    .then((res) => res.json())
    .then((data) => {
        if(data.status === '200') {
            document.getElementById('profile-picture').src = data.data;
            alert("done");
        } else {
            console.log(data.msg);
        }
    })
    .catch((err) => console.log(err))
})

HTML template:

<div class="col-md-6 order-sm-12 my-5">
                                <p class="upload-btn"><i class="fa fa-camera"></i>  Edit profile picture</p>
                                <p class="close-btn"><i class="fas fa-times"></i>  Reset</p>
                                <img class="profile-img" id="profile-picture" data-target="{% if user.customuser.picture %}{{ user.customuser.picture.url }}{% endif %}" src="{% if user.customuser.picture %}{{ user.customuser.picture.url }}{% endif %}" />
                                {% if user == request.user %}
                                    <input id="id_picture" style="visibility:hidden;" name="picture" type="file" accept="image/*" required onchange="document.getElementById('profile-picture').src = window.URL.createObjectURL(this.files[0]);document.getElementById('submit-picture').style.visibility = 'visible';">
                                    <button class="btn vizew-btn w-100 my-3" style="visibility:hidden;" id="submit-picture">Change profile picture</button>
                                {% endif %}
                            </div>

The view function, change_profile_picture returns invalid form and I do not know why. So far, I've noticed that the picture file is not actually sent with the fetch api. I've also tried changing from using Javascript to submit to using normal HTML form tag, it still gives the same error. Changing inherited form class to ModelForm only populates the field with a default. How do I fix it?

I found out in the change_profile view, where I initialized the form with the data submitted, I did not populate the form with request.FILES like so:

<code>
 if request.method == 'POST':
        if request.is_ajax():
            form = UploadPictureForm(request.POST, request.FILES)
<more code>

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