简体   繁体   中英

SOLVED Django file upload with ajax without JQuery

everything is in the title, so before any further explanations there is my code.

{% extends 'informations/userpage.html' %}
{% load static %}
{% block redaction %}
<div class="redaction">
    <form method="POST" enctype="multipart/form-data" action="/redaction/" class="article-post">
        {% csrf_token %}
        <div class="article-picture">
            {% if article.image %}
                {{article.image}}
            {% else %}
                <img class="generic-image" src="{% static 'informations/images/none-picture.svg' %}" alt="Image article">
            {% endif %}
                <img class="edit" id="article-image" src="{% static 'informations/images/edit.svg' %}">
        </div>
        <div id="id01" class="modal" style="display: none;">
            <div class="upload-container">
                <input type='file' name="newImage">
                <div class="button" id="uploadImage" name="upload" value="envoyer">Envoyer</div>
            </div>
        </div>
    </form>
    {% csrf_token %}
    <script id="picturesend">
        var csrf_token = document.getElementsByName('csrfmiddlewaretoken').value
    </script>
    <script type="text/javascript"
            id="django-admin-popup-response-constants"
            src="{% static 'informations/redaction.js' %}">
    </script>
</div>
{% endblock %}
var articleImage = document.getElementById('article-image');
var uploadImage = document.getElementById('uploadPic');

uploadImage.addEventListener('click', displayUpload);
articleImage.addEventListener('click', displayUpload);

function displayUpload() {
    var uploadfile = document.getElementById('id01');
    var uploadPicture = document.getElementById('uploadImage');
    uploadPicture.addEventListener('click', uploadFile);
    uploadfile.style.display='block'
}

function uploadFile() {
    var formData = new FormData();
    var file = document.getElementsByName('newImage');
    var image = document.getElementsByClassName('generic-image')[0];
    formData.append('newImage', file);
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload/', true);
    xhr.onload = function () {
        if (xhr.status === 200) {
            console.log(xhr.responseText);
            image.setAttribute('src',JSON.parse(xhr.responseText));
        } else {
            alert('An error occurred!');
        }
    };
    xhr.setRequestHeader('Content-Type', file.type);
    xhr.setRequestHeader('X-CSRFToken', getCookie('csrftoken'));
    xhr.send(formData);
}

my file model

def userDirectoryPath(instance, filename):
    # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
    return 'user_{0}/{1}'.format(instance.user.username, filename)

class Media(models.Model):
    user = models.ForeignKey(User, null=True , on_delete=models.CASCADE)
    media = models.FileField(upload_to=userDirectoryPath)

my view handling ajax.

@login_required
def upload_media(request):
    user = request.user
    data = {}

    if request.POST:
        newFile = Media()
        newFile.media = request.FILES['newImage']
        newFile.user = user
        newFile.save()
        data.update({"media_url": newFile.media.url})

    return JsonResponse(data)

So now a little bit of explanations, what i want to do, is without JQuery, send file to my server, register the file and add an entry in the database and then return the url with JsonResponse to do whatever I need to with, with javascript.

I'm a beginner I all of these technologies, and I'm intentionally doing it without Jquery. I'm aware that my code writing is not really following the best practice but I hope it's understandable.

The issue with the code that I'm sending, is that when I look at my console.log(xhr.responseText); I see {}, so it seems that it doesn't understand that the request method is a POST method, I tried with if request.method == 'POST': I got the same result. As I don't really know every thing about ajax, I think that the issue went from my javascript code. I've done some search on Internet, but all I get are examples with JQuery, which I don't use.

So if someone see any solutions, or know where I can get one I'll be really grateful, of course if you need more details, I'll give what your need.

Thanks for reading, and eventually helping me.

[UPDATE]

with request.method == "POST" the conditions is True, but the errors occurs inside the if I get MultiValueDictKeyError at /upload/ newImage I've already had this error when I was using a <form> and forgot enctype="multipart/form-data" , now I'm stuck with this.

[SOLVED] After some search, reading my code and some tries, I've saw some errors in my code. Here is the code that works:

function uploadFile() {
    var formData = new FormData();
    var file = document.getElementsByName('newImage')[0];
    var image = document.getElementsByClassName('generic-image')[0];
    formData.append('newImage', file.files[0], file.files[0].name);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", '/upload/', true);
    xhr.onload = function () {
        if (xhr.status === 200) {
            console.log(xhr.responseText);
            image.setAttribute('src',JSON.parse(xhr.responseText));
        } else {
            alert('An error occurred!');
        }
    };
    xhr.setRequestHeader('X-CSRFToken', getCookie('csrftoken'));
    xhr.send(formData);
}

There is no need of the line javascript xhr.setRequestHeader('Content-Type', file.type); and to get the file you need use the attribute files of your input

var file = document.getElementsByName('newImage')[0];
 formData.append('newImage', file.files[0], file.files[0].name);

files[0] because I upload only one file at the time. I hope that my mistakes are helping others.

See you, Problem solved, at least for the file uploading !

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