user3605378
user3605378

Reputation: 1

Django image upload using dropzone

I've been having this problem for a while and I could not find out the solution, I am trying to use dropzone.js to upload images and my form.is_valid() fails. Passing the error : This field is required. Could you help me realize what am I doing wrong?

models.py :

class Image(models.Model):
    item_id = models.ForeignKey(Item,blank=True,null=True)
    image = models.ImageField(upload_to='item_images/%Y/%m/%d')
    def __unicode__(self):
        return smart_unicode(self.image)

forms.py :

class ImageForm(forms.ModelForm):

    class Meta:
        model = Image
        exclude = ['item_id']

views.py :

def upload_image(request):
    if request.method == 'POST':
        form = ImageForm(request.POST, request.FILES)
        if form.is_valid():
            result = 'success'
        return render(request, 'page.html', {'form':form})

page.html:

        <form class="dropzone" id="myDropzone" action="/upload_image/" method="post" enctype="multipart/form-data">
            {% csrf_token %}
        </form>

Upvotes: 0

Views: 1474

Answers (2)

elad silver
elad silver

Reputation: 9675

I don't know if what i show now will help you specifically but you can do like this without using a form, also maybe it will help others here. Working with dropzone made me do a workaround because ajax, files and django combined are always a little complicated.

so in my html i have this code:

<div class="logos">
  <i class="fa fa-upload" id="dropzone_icon" data-name="icon" title="{% trans "Drag and drop or click" %}" alt="{% trans "Drag and drop or click" %}" ></i>
  <input type="hidden" name="icon" value="" >
  <input type="hidden" name="icon_name" value="" >
  <div class="img-holder">
    <img title='{% trans "Upload a Company Icon" %}' id="img_icon" alt='{% trans "Company icon" %}' src="{* icon *}"/>
  </div>
  <label>{% trans "Company Icon" %}</label>
</div>

in my js i got this:

dropz = new Dropzone(value, {
    url: "branding/dropzone",
    maxFiles: 1,
    acceptedFiles: "image/*",
    thumbnail: function(file, dataUrl) {
        /* change existing image */
        var file_type = file.name.split('.');
        file_type = file_type[file_type.length - 1];
        if(!(file_type=="png" || file_type=="jpg" || file_type=="jpeg")){
            createAlert('file type must be .png, .jpg or .jpeg', '#pp_content', 'alert');
            return false;
        }
        $("input[name='icon']").val(dataUrl.split(",")[1]);
        $("input[name='icon_name']").val(file.name);
        $("#img_" + type).prop("src", dataUrl);
        this.removeFile(file);
    },
    previewTemplate: "<span></span>",
    autoProcessQueue: false
});

this tells dropzone to insert into the values into the inputs(the base64 presentation of the image, and the file name) so basically i'm sending the image as a string.

after sending the inputs as a form in the ajax, this is how i handle them in my views.py:

import datetime
from django.core.files.base import ContentFile

def base64_to_image(img_b64,img_name):
"""
Creates image file from bas64 encoded data
:param img_b64: base64 data
:param img_name: filename for created image
:return: file or false if there's no data
"""
if img_b64:
    image_data = b64decode(img_b64)
    img_file = ContentFile(image_data,datetime.datetime.now().strftime("%y%d%m_%H%M%S") + img_name)
    return img_file
else:
    return False

company.icon = base64_to_image(request.POST["icon"], request.POST["icon_name"])
company.save()

this is my work around working with dropzone, maybe it will help others here as well

Upvotes: 1

Sander van Leeuwen
Sander van Leeuwen

Reputation: 3033

The form expects an input with type 'file' and name 'image'.

Upvotes: 1

Related Questions