Zorgan
Zorgan

Reputation: 9133

Remote image upload performs different than development server

My local development and live development server have the exact same code and database (all static/media files upload to s3 storage).

I have a Post model with an image field. My Post has an image upload field which uploads via AJAX to my s3 storage. In both my local and live server, the image successfully uploads and the url of that image in my s3 bucket is saved. So when I submit the Post in my local server, it doesn't upload again, I just point to the URL when I render the image.

However, my remote server doesn't do this. After I have uploaded the image via AJAX, when I submit the Post form, it then submits the image again (it shows the upload progression on my browser - 3%, 5%, 10% etc...).

Any idea why this happens? My code is here:

models

class Post(models.Model):
    image = models.FileField(null=True, blank=True)

views

def post(request):
    if request.user.is_authenticated():
        form_post = PostForm(request.POST or None, request.FILES or None)
        if form_post.is_valid():
            instance = form_post.save(commit=False)
            instance.user = request.user
            ...
            if instance.image:
                instance.imageURL = "https://s3.us-east-2.amazonaws.com/my-bucket/media/%s" % filename
                instance.image = None #this prevents re-upload upon form submission

            instance.save()

            return HttpResponseRedirect('/')
        else:
            form_post = PostForm()

        context = {
            'form_post': form_post,
        }

        return render(request, 'post/post.html', context)
    else:
        return HttpResponseRedirect("/accounts/signup/")

ajax view

def upload_image(request):
    random_filename = request.POST.get('random_filename')
    if request.is_ajax():
        if request.FILES:
            img = request.FILES.get('image')


        session = boto3.Session(
            aws_access_key_id=AWS_ACCESS_KEY_ID,
            aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
        )
        s3 = session.resource('s3')

        s3.Bucket('my-bucket').put_object(Key='media/%s' % random_filename, Body=img)
        return HttpResponse()

    else:
        return HttpResponse()

template

<input id="id_image" type="file" name="image" />

JS

$('input#id_image').on('change', function(e) {
    var file = $('input[type=file]')[0].files[0];
    var formData = new FormData();

    $('.add_file_div h3').hide();
    $('.add_file_label').css({
    'border-radius': '5px',
    'box-shadow': '5px',
    });
    var imagePath = URL.createObjectURL(e.target.files[0]);
    var random_filename = random_string();

    formData.append('image', file);
    formData.append('csrfmiddlewaretoken', $("input[name='csrfmiddlewaretoken']").val());
    formData.append('random_filename', random_filename);

    $.ajax({
        url: '/upload_image/',
        data: formData,
        type: 'POST',
        contentType: false,
        processData: false,
        success: function(){
            console.log('SUCCESSFULLY UPLOADED');
            $('.add_file_label').css('opacity', '1');
            $('.add_file_label').css('background', 'url(' + imagePath + ') scroll no-repeat center/cover');
            $('.loading_spinner').css('visibility', 'hidden');
        }
    });
    $('.add_file_label').css('background', 'url(' + imagePath + ') scroll no-repeat center/cover');
    $('.add_file_label').css('opacity', '0.4');
    $('.loading_spinner').css('visibility', 'visible');
    console.log(imagePath);

    $('.add_file_label').append('<input class="temp_s3_url" type="hidden" name="temp_s3_url">');
    $('.temp_s3_url').val(random_filename);
    $('input#id_imageURL').hide();
    $('#delete_preview_image').show();
});

PS: My nginx has client_max_body_size 200m; so that's not the problem

Upvotes: 1

Views: 137

Answers (1)

Tarun Lalwani
Tarun Lalwani

Reputation: 146610

I think the same issue may be happening locally also. But when you are local the speed is fast enough for you to not see a upload progress bar. The thing is that you should clear your file field when you have had a success in the ajax upload

how to reset <input type = "file">

so inside

success: function(){
  console.log('SUCCESSFULLY UPLOADED');
  $('.add_file_label').css('opacity', '1');
  $('.add_file_label').css('background', 'url(' + imagePath + ') scroll no-repeat center/cover');
  $('.loading_spinner').css('visibility', 'hidden');
}

You would reset the file element to make it a blank value, else it will get submitted with the form.

Another option could be to just give the file input field a id and not a name. If there is no name attached to a input element it doesn't get submitted with a form

Upvotes: 1

Related Questions