尝试使用 django 和 dropzone/

Posted

技术标签:

【中文标题】尝试使用 django 和 dropzone/【英文标题】:Trying to use django and dropzone/ 【发布时间】:2015-07-16 15:55:57 【问题描述】:

我正在尝试将 dropzone.js 与 django 一起使用。

我在这里遵循有点过时的指南 (https://amatellanes.wordpress.com/2013/11/05/dropzonejs-django-how-to-build-a-file-upload-form/)

我强烈怀疑我的观点有问题。

def test(request):
    print "test view has been called"
    if request.method == 'POST':
        print "test request method is POST"
        form = UploadFileForm(request.POST, request.FILES)
        print request
        print request.FILES
        if form.is_valid():
            new_file = AttachedFiles(attachedfile=request.FILES['file'])
            new_file.save()
            id = new_file.pk
            print id
            print "test form valid"
            return HttpResponse(json.dumps('id': id), content_type="application/json")
       print "test form not valid"
   else:
       form = UploadFileForm()
   data = 'form': form
   return render_to_response('mediamanager/test.html', data, context_instance=RequestContext(request))

我已经测试过使用 dropzone 代码提交它

        <!-- IMPORTANT enctype attribute! -->
    <form id="my_dropzone" class="dropzone" action="/mediamanager/test/" method="post" enctype="multipart/form-data">
        % csrf_token %
     <button id="submit-all">
        Submit all files
    </button>
    </form>
    <script src="% static 'dropzone/js/dropzone.js' %"></script>
    <script type="text/javascript">
        Dropzone.options.myDropzone = 

            // Prevents Dropzone from uploading dropped files immediately
            autoProcessQueue : true,

            init : function() 
                var submitButton = document.querySelector("#submit-all")
                myDropzone = this;

                submitButton.addEventListener("click", function() 
                    myDropzone.processQueue();
                    // Tell Dropzone to process all queued files.
                );

                // You might want to show the submit button only when
                // files are dropped here:
                this.on("addedfile", function() 
                    // Show submit button here and/or inform user to click it.
                    console.log("blah")
                );
            
        ;
    </script>

还有一个基本形式

<form action="% url "test" %" method="post" enctype="multipart/form-data">
  % csrf_token %
<input type="file" name="file" />
<input type="submit" value="Submit">
</form>

并且该表单永远无效。 我正在使用建议的模型格式

class UploadFileForm(forms.ModelForm):
    class Meta:
        model = AttachedFiles

【问题讨论】:

你要做什么,你是上传图片还是什么类型的文件? 我希望在这个阶段能够上传任何类型的文件。最后,我希望它们附加到另一个模型。 最后我想要一个多文件上传器将多个文件附加到一个模型.....我已经为此苦苦挣扎了好几个星期了。 我也遇到过这个问题,我必须上传多张图片。我用我的方式解决了这个问题。 ***.com/questions/28623094/… 【参考方案1】:

您可以像处理任何其他多部分表单帖子一样处理 Dropzone 帖子。

我是这样处理的:

@login_required
@usertype_required
def upload_picture(request, uid=None):
    """
    Photo upload / dropzone handler
    :param request:
    :param uid: Optional picture UID when re-uploading a file.
    :return:
    """
    form = PhotoUploadForm(request.POST, request.FILES or None)
    if form.is_valid():
        pic = request.FILES['file']
        # [...] Process whatever you do with that file there. I resize it, create thumbnails, etc.
        # Get an instance of picture model (defined below) 
        picture = ...         
        picture.file = pic
        picture.save()
        return HttpResponse('Image upload succeeded.')
    return HttpResponseBadRequest("Image upload form not valid.")

表格很简单

class PhotoUploadForm(forms.Form):
    # Keep name to 'file' because that's what Dropzone is using
    file = forms.ImageField(required=True)

在您的模型中,您需要设置 upload_to:

class Picture(models.Model):
    [...]
    # Original
    file = models.ImageField(upload_to=get_upload_path)

这是我的上传路径生成器,但你可以放任何东西

def get_upload_path(instance, filename):
    """ creates unique-Path & filename for upload """
    ext = filename.split('.')[-1]
    filename = "%s.%s" % (instance.p_uid, ext)
    d = datetime.date.today()
    username = instance.author.username

    #Create the directory structure
    return os.path.join(
        'userpics', username, d.strftime('%Y'), d.strftime('%m'), filename
    )

不要忘记 html 表单本身中的 csrf_token(我在它上面使用了一个 angularJS 指令,所以对你来说会有所不同)

<form action="% url 'upload_picture' %" class="dropzone" drop-zone>
    % csrf_token %
    <div class="fallback">
        <h3>Your browser is not supported.</h3>
        <strong>
            <a href="https://browser-update.org/update.html" target="_blank">Click here for instructions on how to update it.</a>
        </strong>
        <p>You can still try to upload your pictures through this form: </p>
        <p>
            <input name="file" type="file" multiple />
            <input type="submit" value="Upload" />
        </p>
     </div>
 </form>

【讨论】:

【参考方案2】:

我通过在此处修改引导示例(我正在使用引导)使 dropzone js 工作:http://www.dropzonejs.com/bootstrap.html

我不使用任何形式。我有一个视图来处理来自 dropzone 的即将到来的 ajax 帖子。这是我的视图代码的要点:

class AjaxUploadView(View):
    """
        View for uploading via AJAX.
    """
    def post_ajax(self, request, *args, **kwargs):
        uploaded_file = request.FILES['file']
        # Do stuff with file
        # Return appropriate response

希望对你有帮助。

【讨论】:

以上是关于尝试使用 django 和 dropzone/的主要内容,如果未能解决你的问题,请参考以下文章

我正在尝试使用 Django CMS 和模板。但在编辑模板时出错

尝试复制文件夹时,Google API和Django出现400错误

在 Python 中使用 Django - 尝试导入时未定义视图

Django:尝试使用保留创建会议室 API

Django 和 SuspiciousFileOperation:检测到路径遍历尝试

使用南(django)和 MySQL 进行模式迁移