File Upload Issue

4 views
Skip to first unread message

Bo Shi

unread,
Oct 15, 2005, 3:57:39 AM10/15/05
to Django users
Hi All,

I've been playing with FileField and file uploading.

I do have a problem that I can't seem to solve; when a file gets
uploaded, it is placed in the media directory under some random
filename the client was using. I would like to normalize this filename
so that

foo.txt

is saved on the server as

MEDIA_ROOT/text/username_fileid.txt

I have tried combining _post_save() and os.rename(...) to some limited
success but am not able to reset my FileField to the new file path (my
assumption is that using save() inside _post_save() causes infinite
recursion, no?). Clearly said strategy is an ugly hack with some major
problems.

Is there an elegant way to do this?

Regards,
Bo

Luke Plant

unread,
Oct 15, 2005, 3:41:39 PM10/15/05
to django...@googlegroups.com
> I have tried combining _post_save() and os.rename(...) to some limited
> success but am not able to reset my FileField to the new file path (my
> assumption is that using save() inside _post_save() causes infinite
> recursion, no?). Clearly said strategy is an ugly hack with some
> major problems.
>
> Is there an elegant way to do this?

Could you not simply check in the _post_save() method whether the file
already has a correct filename, and if so do nothing, otherwise move it
and save the object? That would avoid any infinite recursion.

Luke

--
"God demonstrates his love towards us in this, that while we were still
sinners, Christ died for us." (Romans 5:8)

Luke Plant || L.Plant.98 (at) cantab.net || http://lukeplant.me.uk/

Nebojša Đorđević - nesh

unread,
Oct 16, 2005, 6:11:19 AM10/16/05
to django...@googlegroups.com
On 15-10-2005, at 9:57, Bo Shi wrote:

> I have tried combining _post_save() and os.rename(...) to some limited
> success but am not able to reset my FileField to the new file path (my
> assumption is that using save() inside _post_save() causes infinite
> recursion, no?). Clearly said strategy is an ugly hack with some
> major
> problems.

IMO you don't save() in _pre_save(). This function is called *before*
record is saved so any modification are automatically saved.

I'm using something like this (you can ignore quoting stuff):
...
def _pre_save(self):
from utils.utils import store_file
self.image = rename_by_field(self.image, self.slug)
self.logo_image = rename_by_field(self.logo_image, self.slug)
#

def rename(old_name, new_name):
""" rename image old_name -> new_name """
try:
shutil.move(old_name, new_name)
return new_name
except IOError:
return old_name
# rename

_HEX_SUB = re.compile(r'\%([0-9A-F]{2})')
def rename_by_field(file_path, req_name):
if file_path.strip() == '': return '' # no file uploaded

old_name = os.path.basename(file_path)
path = os.path.dirname(file_path)

name, ext = os.path.splitext(old_name)

# make new name, all filenames are LOWERCASED, unsafe characters
are encoded as [<HEX>]
# I don't like %xx url type of quoting ;)
new_name = urllib.quote(req_name.lower(), safe='')
new_name = _HEX_SUB.sub(r'[\1]', new_name) + ext

dest_path = os.path.join(path, new_name)

if new_name != old_name:
return rename(file_path, dest_path)
else:
return file_path
#
#


---
Nebojša Đorđević - nesh
Studio Quattro - Niš - SCG

http://djnesh.blogspot.com/ | http://djnesh-django.blogspot.com/
Registered Linux User 282159 [http://counter.li.org]



Bo Shi

unread,
Oct 16, 2005, 2:43:41 PM10/16/05
to Django users
Hey Nesh,

Moving the rename logic to _pre_save() would be the best way of doing
things but I have a problem where I rename the uploaded file into one
based on it's primary key. While in _pre_save(), self.id is None, so
is there a way to access the value that will become the primary key?

Bo

Nebojša Đorđević - nesh

unread,
Oct 16, 2005, 3:05:41 PM10/16/05
to django...@googlegroups.com
Well, I never (yet) run in this kind of a problem. Generally I always
use some kind of SlugField as a secondary primary key (unique) that
gives me a pretty (and human readable) URLs. It's not possible to
know under witch id record will be saved.

You can try to move rename logic into _post_save(). IIRC when you hit
_post_save object is already in db so self.id will have a value.
After renaming file and updating image field you must again save()
object.
Reply all
Reply to author
Forward
0 new messages