0

I am creating a form that allows a user to select a image and upload it using Django and AJAX. This process works fine but the problem is that the uploaded image isn't being displayed on the screen however I did specify a div for it.

These are the steps that I followed:

  • Create a model that handle the uploaded image.
  • Create a path for the function.
  • Create the function that uploads the selected image.
  • Create the template and AJAX function.

models.py:

class photo(models.Model):
    title = models.CharField(max_length=100)
    img = models.ImageField(upload_to = 'img/')

home.html:

 <form method="POST" id="ajax"  enctype="multipart/form-data">
        {% csrf_token %}
        Img:
        <br />
        <input type="file" name="img">

        <br />
        <br />
        <button id="submit"  type="submit">Add</button>

    </form>



<h1> test </h1>
    <div id="photo">
        <h2> {{ photo.title }}</h2>
        <img src="{{ photo.img.url }}" alt="{{ photo.title }}">
    </div>






 $('#ajax').submit(function(e) {
                e.preventDefault();
                var data = new FormData($('#ajax').get(0));
                console.log(data)

                $.ajax({
                    url: '/upload/', 
                    type: 'POST',
                    data: data,
                    contentType: 'multipart/form-data',
                    processData: false,
                    contentType: false,
                    success: function(data) {
                        // alert('gd job');
                        $("#photo").html('<h2> {{'+data.title+'}}</h2> <img src="{{'+data.img.url+ '}}" alt="{{ photo.title }}">')

                    }
                });
                return false;
            });

views.py:

def upload(request):
    if request.method == 'POST':
        if request.is_ajax():
            image = request.FILES.get('img')
            uploaded_image = photo(img = image)
            uploaded_image.save()
            photo=photo.objects.first()    

    # return render(request, 'home2.html')
    return HttpResponse(photo)

I expect that after the user uploads the image and the image I stored in the database, the image must be displayed on the screen.

new Q Open Wid
  • 2,225
  • 2
  • 18
  • 34
Django Dg
  • 97
  • 4
  • 19
  • You are trying to show the image as I suggested you that day. Check here:https://stackoverflow.com/questions/56493419/how-to-display-uploaded-image-on-the-screen-using-django-and-ajax check my answer properly you are doing a little mistake – chirag soni Jun 15 '19 at 08:17
  • @chiragsoni yes you are right i tried your answer but it did not display it and i did not find the error . but i am suspecting that the error is in the **success function** – Django Dg Jun 15 '19 at 08:22
  • You properly follow my answer you will be able to resolve it. Best of luck! – chirag soni Jun 15 '19 at 08:23
  • @chiragsoni still did not find where is the error exactly because when i debug its working as it should without displaying the image. – Django Dg Jun 15 '19 at 09:02
  • Bro I am really sorry but usually, people would like to answer and help you only when you will appreciate their answers right? I already spend my time to help you here:https://stackoverflow.com/questions/56493419/how-to-display-uploaded-image-on-the-screen-using-django-and-ajax but no appreciation from your side. Please make a habit of appreciating others to get the good answers always. It is for your benit only. – chirag soni Jun 15 '19 at 09:08
  • yes you are right but the reason that i did not checked your answer is because the people that will respond to this question will assume that its a duplicated question and that already answered. other than that i thank you for your time and your help and i appreciate that you are answering this second question. – Django Dg Jun 15 '19 at 09:12
  • Ok no problem. But please make this habit to become a very good developer. Going forward you would be able to post good ans only if you get good answers and this is how your doubts would be clear. – chirag soni Jun 15 '19 at 09:31
  • You are doing little mistake in you code. At this line: `$("#photo").html('

    {{'+data.title+'}}

    {{ photo.title }}')` you are trying to embed html code but it looks like there is no such `id="photo" ` in your html template. So go ahead and add a div tag with this id.
    – chirag soni Jun 15 '19 at 09:33
  • success fn code is perfectly fine but it is not able to find the `id="photo"` in the template so how you would be able to see the image after upload. – chirag soni Jun 15 '19 at 09:34
  • no the ID photo exist in the html code where photo is the id for the DIV that contain the title and the photo itself. – Django Dg Jun 15 '19 at 09:36
  • check my question i add the existing code about the photo id to my question – Django Dg Jun 15 '19 at 09:38
  • where is that id show in the code you showed?' – chirag soni Jun 15 '19 at 09:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/194981/discussion-between-chirag-soni-and-django-dg). – chirag soni Jun 15 '19 at 09:39
  • Possible duplicate of [how to display uploaded image on the screen using django and ajax](https://stackoverflow.com/questions/56493419/how-to-display-uploaded-image-on-the-screen-using-django-and-ajax) – Ivan Starostin Jun 15 '19 at 11:00

2 Answers2

5

For using ImageField you have to install Pillow

pip install pillow

Let's go through your code and modify it a little.

models.py

from django.db import models


# Create your models here.
class Photo(models.Model):
    title = models.CharField(max_length=100)  # this field does not use in your project
    img = models.ImageField(upload_to='img/')

views.py I splitted your view into two views.

from django.shortcuts import render
from django.http import HttpResponse
from .models import *
import json


# Create your views here.
def home(request):
    return render(request, __package__+'/home.html', {})


def upload(request):
    if request.method == 'POST':
        if request.is_ajax():
            image = request.FILES.get('img')
            uploaded_image = Photo(img=image)
            uploaded_image.save()
            response_data = {
                'url': uploaded_image.img.url,
            }
    return HttpResponse(json.dumps(response_data))

urls.py

from django.urls import path
from .views import *
from django.conf.urls.static import static
from django.conf import settings

app_name = __package__

urlpatterns = [
    path('upload/', upload, name='upload'),
    path('', home, name='home'),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

settings.py

MEDIA_URL = '/img/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'img')

home.html

{% load static %}
<html>
    <head>
        <script src="{% static 'photo/jquery-3.4.1.js' %}"></script>
        <script>
            $(document).ready(function() {
                $('#ajax').submit(function(e) {
                    e.preventDefault();  // disables submit's default action
                    var data = new FormData($('#ajax').get(0));
                    console.log(data);

                    $.ajax({
                        url: '/upload/',
                        type: 'POST',
                        data: data,
                        processData: false,
                        contentType: false,
                        success: function(data) {
                            data = JSON.parse(data); // converts string of json to object
                            $('#photo').html('<img src="'+data.url+ '" />');
                            // <h2>title</h2> You do not use 'title' in your project !!
                            // alt=title see previous comment
                        }
                    });
                    return false;
                });
            });

        </script>    
    </head>
    <body>
        <form method="POST" id="ajax">
            {% csrf_token %}
            Img:
            <br />
            <input type="file" name="img" />
            <br />
            <br />
            <button id="submit"  type="submit">Add</button>
        </form>

        <h1> test </h1>
        <div id="photo"></div>
    </body>
</html>

Do not use template variables in javascript {{'+data.title+'}} ! Send a string to HttpResponse() as an argument, in return HttpResponse(photo) photo is an object.

shmakovpn
  • 751
  • 9
  • 10
  • this was the solution thank you. so if i want to upload several photo like an album it will be the same logic and process right ? – Django Dg Jun 19 '19 at 09:02
  • Yes, also you can use 'class' instead of 'id' in html form and script. Something like `$('.ajax').each(function () { $(this).submit( todo ); });` – shmakovpn Jun 20 '19 at 03:56
  • This answer is great, thank you shmakovpn. I was looking for this line " $('#photo').html('');". You saved me a lot of efforts. – Saleh May 07 '20 at 03:16
1

For multiple forms:

views.py

def home(request):
    context = {
        'range': range(3),
    }
    return render(request, __package__+'/home.html', context)

home.html

{% load staticfiles %}
<html>
    <head>
        <script src="{% static 'photo/jquery-3.4.1.js' %}"></script>
        <script>
            $(document).ready(function() {
                $('.ajax').each(function () {
                    $(this).submit(function (e) {
                        e.preventDefault();  // disables submit's default action
                        var data = new FormData($(this).get(0));
                        var imageForm = $(this);
                        $.ajax({
                            url: '/upload/',
                            type: 'POST',
                            data: data,
                            processData: false,
                            contentType: false,
                            success: function(data) {
                                data = JSON.parse(data); // converts string of json to object
                                imageForm.parent().find('.photo').html('<img src="'+data.url+ '" />');
                                console.log(imageForm);
                            }
                        });
                        return false;
                    });
                });
            });
        </script>
    </head>
    <body>
        {% for i in range %}
            <div style="border: 1px solid black">
                <form method="POST" class="ajax">
                    {% csrf_token %}
                    <div class="upload-label">Img-{{ i }}:</div>
                    <input type="file" name="img" />
                    <br />
                    <br />
                    <button class="submit"  type="submit">Add</button>
                </form>
                <div class="image-label"> Image: </div>
                <div class="photo">No image yet</div>
            </div>
        {% endfor %}
    </body>
</html>
shmakovpn
  • 751
  • 9
  • 10