📜 ⬆️ ⬇️

Uploading multiple files to Django - Multifile upload Django SWFUploader

Django provides excellent tools for quickly building a back-end without unnecessary gestures. However, the creation on its basis of the gallery is associated with a lot of manual work on downloading each file separately.

There are several solutions to this problem:
  1. archive download and unpacking on the server,
  2. use of a special field,
  3. imitation of multiple post requests.

I chose the last option, as in this case you need to make a minimum of changes. All operations are performed on the client. We will use swfuploader for this.

The idea is simple; we modify the standard add interface so that we can intercept the save object event. The filled fields will be used as a template for creating a set of objects for the selected files.
')
So perform the following steps.

  1. We download the swfupload example set: http://swfupload.googlecode.com/files/SWFUpload%20v2.2.0.1%20Samples.zip .
  2. from it the following files fall to us:

  3. We put them in the djangosite / media / js / swfupload media directory.
  4. Register js in djangosite / gallery / admin.py:
    from django.contrib import admin
    from djangosite.gallery.models import Image

    class ImageAdmin(admin.ModelAdmin):
    class Media:
    js = (
    '/media/js/jquery.min.js' ,
    '/media/js/swfupload/swfupload.js' ,
    '/media/js/swfupload/swfupload.queue.js' ,
    '/media/js/swfupload/swfupload.cookies.js' ,
    '/media/js/multiupload.js' ,
    )

    admin.site.register(Image,ImageAdmin)


    * This source code was highlighted with Source Code Highlighter .
  5. Create a control js-code djangosite / media / js / multiupload.js

    jQuery().ready( function (e){<br> DjangoMultiUpload.init();<br>});<br><br><br> var DjangoMultiUpload = new function (){<br> <br> // <br> this .swfu = null ;<br> this .gui_submit = null ;<br> this .old_upload = null ;<br> this .busy = false ;<br> <br> // swfupload <br> this .debug = false ;<br> this .flash_url = "/media/js/swfupload/swfupload.swf" ;<br> this .upload_url = "" ;<br><br> this .file_size_limit = "100 MB" ;<br> this .file_types = "*.jpg;*.gif;*.jpeg" ;<br> this .file_types_description = " " ;<br> this .file_upload_limit = 100;<br> this .file_queue_limit = 0;<br> this .custom_settings = {<br> progressTarget : "fsUploadProgress" ,<br> cancelButtonId : "btnCancel" <br> };<br> this .button_image_url = "/media/js/swfupload/XPButtonUploadText_61x22.png" ,<br> this .button_width = "61" ,<br> this .button_height = "22" ,<br> this .button_placeholder_id = "spanButtonPlaceHolder" , <br> this .file_post_name = null ;<br><br> // Linux ( ). <br> // input file, <br> // . <br> // <br> // ? <br> // Ui. <br> // swfupload <br> this .init = function (e){<br><br> if (navigator.appVersion.indexOf( "Linux" )!=-1)<br> return false ;<br> <br> this .old_upload = jQuery( 'input[type=file]' );<br> <br> if ( this .old_upload.size() != 1)<br> return false ;<br> <br> if (!jQuery( "label[for=" + this .old_upload.attr( 'id' ) + "]" ).hasClass( 'required' ))<br> return false ;<br><br> if ( this .old_upload.prev().get(0).tagName == "BR" )<br> return false ;<br> <br> this .gui();<br> <br> this .swfu = new SWFUpload( this );<br> <br> }<br> <br> // input file <br> // swfuploader <br> // <br> // <br> this .gui = function (){<br> <br> this .file_post_name = this .old_upload.attr( 'name' );<br> <br> jQuery( "<span id='spanButtonPlaceHolder'></span>" ).insertAfter( this .old_upload);<br> <br> <br> <br> jQuery( 'form' ).submit( function (e){<br> DjangoMultiUpload.submit(e);<br> return false ;<br> });<br> <br> this .old_upload.hide();<br> jQuery( 'input[name=_continue]' ).hide();<br> jQuery( 'input[name=_addanother]' ).hide();<br> <br> }<br> <br> // <br> // <br> // <br> this .submit = function (e){<br> <br> if ( this .busy){<br> alert( 'Uploading. Please wait.' );<br> return false ;<br> }<br> <br> if ( this .prepare_post_data()){<br> <br> jQuery( 'input[name=_save]' ).attr( 'value' ,0);<br> <br> this .busy = true ;<br> <br> this .swfu.startUpload();<br> }<br> <br> return false ;<br> <br> }<br> <br> // <br> // postdata swfuploader <br> // false <br> // input-file <br> // linux <br> this .prepare_post_data = function (){<br> <br><br> <br> var labels = jQuery( 'label' );<br> <br> if (!labels.size())<br> return 0;<br> <br> var field = null ;<br> var label = null ;<br> var success = true ;<br> <br> for (i = 0 ; i < labels.size();i++ )<br> {<br> <br> label = jQuery(labels.get(i))<br> <br> if (label.attr( 'for' ) == this .old_upload.attr( 'id' ))<br> continue ;<br><br> field = jQuery( '#' + label.attr( 'for' ));<br> <br> if (label.hasClass( 'required' ) && !field.attr( 'value' )){<br> label.css( 'color' , 'red !important' );<br> success = false ;<br> }<br><br> this .swfu.addPostParam(field.attr( 'name' ), field.attr( 'value' ));<br> <br> }<br> <br> this .swfu.addPostParam( 'file_post_name' , this .file_post_name)<br> <br> return success;<br> <br> }<br> <br> // <br> this .upload_complete_handler = function (file)<br> {<br> jQuery( 'input[name=_save]' ).attr( 'value' , parseInt(jQuery( 'input[type=submit]' ).attr( 'value' ))+1)<br> };<br> <br> // <br> this .queue_complete_handler = function (numFilesUploaded)<br> {<br> <br> this .busy = false ;<br> <br> if (! this .settings.debug){<br> window.location= "../" ;<br> }<br> }; <br> <br> // <br> this .file_queued_handler = function (file){};<br> this .file_queue_error_handler = function (file, errorCode, message){};<br> this .file_dialog_complete_handler = function (numFilesSelected, numFilesQueued){};<br> this .upload_start_handler = function (file){};<br> this .upload_progress_handler = function (file, bytesLoaded, bytesTotal){};<br> this .upload_success_handler = function (file, serverData){};<br> this .upload_error_handler = function (file, errorCode, message){};<br> <br>};<br><br> <br><br> <br> <br> * This source code was highlighted with Source Code Highlighter .


  6. I use jQuery everywhere in the admin panel. If you do not have it, just put djangosite / media / js / jquery.min.js.
  7. And now a little messy hacking. In djangosite / gallery / middleware.py we write:

    from django.conf import settings

    class MultiUploadHacksMiddleware( object ):
    def process_request(self, request):

    # flash sessionid
    # POST
    if request.POST.has_key(settings.SESSION_COOKIE_NAME):
    request.COOKIES[settings.SESSION_COOKIE_NAME] = \
    request.POST[settings.SESSION_COOKIE_NAME]

    # POST
    #
    if request.POST.has_key( "file_post_name" ) and request.FILES.has_key( "Filedata" ):
    request.FILES[request.POST[ "file_post_name" ]] = request.FILES[ "Filedata" ]
    del request.FILES[ "Filedata" ]


    * This source code was highlighted with Source Code Highlighter .


  8. Add our hacks in settings.py

    MIDDLEWARE_CLASSES = (
    'djangosite.gallery.middleware.MultiUploadHacksMiddleware' ,
    'django.middleware.common.CommonMiddleware' ,
    'django.contrib.sessions.middleware.SessionMiddleware' ,
    'django.contrib.auth.middleware.AuthenticationMiddleware' ,
    )


    * This source code was highlighted with Source Code Highlighter .



Done, now our users can load photos in batches. You can go further - add progress bar and other bells and whistles, but in my case it was not necessary.

Limitations:


Ideally, I would like to:


Just in case the demo .

Source: https://habr.com/ru/post/89116/


All Articles