Generate a random directory for files to be uploaded

128 views
Skip to first unread message

Matt Lind

unread,
Nov 23, 2013, 10:33:59 AM11/23/13
to django...@googlegroups.com
So I am trying to modify django-jfu ( a multi uploader) to send files to a unique directory for every unique upload session performed.  This is just due to my application's requirements and to prevent file collisions during the operations later down the road in my app.

Anyway, here is views.py (I think the most relevant portion anyway, I could be wrong)

def upload( request ):

    # The assumption here is that jQuery File Upload
    # has been configured to send files one at a time.
    # If multiple files can be uploaded simulatenously,
    # 'file' may be a list of files.
    #Create the file object
    file = upload_receive( request )

    #Create an instance of our Uploader Class and pass it the file object
    instance = UpFile ( file = file )
    #Save the file object
    instance.save() 

And the "UpFile" class in models.py:

class UpFile(models.Model):
    file = models.FileField( upload_to = MEDIA_ROOT+'/'+"".join([random.choice(string.ascii_letters) for n in xrange(12)]))

The problem I am having is that it appears that the "random" section at the tail end of the "upload_to" option in models,py is processed only once when the server is started (or restarted).

This won't work for my particular application, as I need the "top level" for any uploaded of a set of files to be unique.

For example if I have the following "upload sessions"

Session 1:  User only uploaded a single file.  A new random/unique directory should be generated under MEDIA_ROOT, and the file should be placed in that directory.
Session 2:  User uploaded 2 files.  A new random/unique directory should be generated under MEDIA_ROOT, and BOTH files should be uploaded to that directory (NOT a different directory per file)
Session 3:  User uploaded 100 files.  Like session 2 above, a new random/unique directory should be generated under MEDIA_ROOT and all 100 files should be placed underneath.

Later on I plan on cleaning house, but for now simply getting that logic down will get me moving again...

Thanks for any help you can provide.

Michael Manfre

unread,
Nov 24, 2013, 10:31:34 AM11/24/13
to django...@googlegroups.com
There are two things that you'll need to do. Set the random directory name on the UpFile instance in the view and define a function to use with upload_to that uses the random directory name on the instance to define the file's target path.


Regards,
Michael Manfre

Matt Lind

unread,
Dec 5, 2013, 7:23:52 AM12/5/13
to django...@googlegroups.com
Ok, I get what what you're saying, but I seem to be having a heck of a time getting the randDir passed into the instance to perform the upload.

Here is the new code snippets:

views.py
instance = Upfile( file = file)
instance.upload(randDir)

models.py

@staticmethod
def upload(randDir)
   file = models.FileField( upload_to = MEDIA_ROOT+'/'+randDir)

I am using @staticmethod as I found that otherwise I needed to pass "self" and kept getting a NameError "self" not defined.

The error I currently get with the above code is:

TypeError: 'file' is an invalid keyword argument for this function

When clicking my "upload" button.

Thanks

Daniel Roseman

unread,
Dec 5, 2013, 9:10:13 AM12/5/13
to django...@googlegroups.com
On Thursday, 5 December 2013 12:23:52 UTC, Matt Lind wrote:
Ok, I get what what you're saying, but I seem to be having a heck of a time getting the randDir passed into the instance to perform the upload.

Here is the new code snippets:

views.py
instance = Upfile( file = file)
instance.upload(randDir)

models.py

@staticmethod
def upload(randDir)
   file = models.FileField( upload_to = MEDIA_ROOT+'/'+randDir)

I am using @staticmethod as I found that otherwise I needed to pass "self" and kept getting a NameError "self" not defined.

The error I currently get with the above code is:

TypeError: 'file' is an invalid keyword argument for this function

When clicking my "upload" button.

Thanks


You can't do that: model fields need to be defined in the model itself, at declaration time.

But you seem to have missed the bit in the documentation[1] which describes how upload_to can be a callable, which does exactly what you want.

def my_upload_to(instance, filename)
    directory = "".join(random.choice(string.ascii_letters) for n in xrange(12))
    return os.path.join(MEDIA_ROOT, directory, filename)

class UpFile(models.Model):
    file = models.FileField(upload_to=my_upload_to)



--
DR.

Matt Lind

unread,
Dec 5, 2013, 9:11:02 AM12/5/13
to django...@googlegroups.com
I should also state that further down in the code I make use of snippets like:

basename = os.path.basename( instance.file.file.name )

So by not passing and uploading the file right away it seems like those snippets don't work anymore


On Sunday, November 24, 2013 10:31:34 AM UTC-5, Michael Manfre wrote:

Matt Lind

unread,
Dec 5, 2013, 9:43:33 AM12/5/13
to django...@googlegroups.com
I did miss that thanks!

However, I now seem to have an issue with the def my_upload_to(instance, filename) line.

Apparently "self" nor "instance" works here, and so I am getting the error 1 argument given when I need "two".

@staticmethod doesn't seem to want to work properly either.

Thanks again!

Matt Lind

unread,
Dec 5, 2013, 9:50:47 AM12/5/13
to django...@googlegroups.com
Disregard.  I found my error.  I was trying to pass something I shouldn't have.  This seems to be working now.

Thanks again!

On Thursday, December 5, 2013 9:10:13 AM UTC-5, Daniel Roseman wrote:
Reply all
Reply to author
Forward
0 new messages