我试图在文件的上传保存方法中重命名文件。我正在将文件重命名为文件主键和文件标题的组合。
首次上传文件,上传新文件以及文件或文件标题没有任何更改时,我都能使用它。
但是,当文件的标题发生更改,并且系统尝试将旧文件重命名为新路径时,我收到以下错误:
WindowsError at /admin/main/file/1/
(32, 'The process cannot access the file because it is being used by another process')
我真的不知道怎么解决这个问题。我试过把文件复制到新路径。这有效,但我不知道我可以删除旧版本。
缩短模型:
class File(models.Model):
nzb = models.FileField(upload_to='files/')
name = models.CharField(max_length=256)
name_slug = models.CharField(max_length=256, blank=True, null=True, editable=False)
def save(self):
# Create the name slug.
self.name_slug = re.sub('[^a-zA-Z0-9]', '-', self.name).strip('-').lower()
self.name_slug = re.sub('[-]+', '-', self.name_slug)
# Need the primary key for naming the file.
super(File, self).save()
# Create the system paths we need.
orignal_nzb = u'%(1)s%(2)s' % {'1': settings.MEDIA_ROOT, '2': self.nzb}
renamed_nzb = u'%(1)sfiles/%(2)s_%(3)s.nzb' % {'1': settings.MEDIA_ROOT, '2': self.pk, '3': self.name_slug}
# Rename the file.
if orignal_nzb not in renamed_nzb:
if os.path.isfile(renamed_nzb):
os.remove(renamed_nzb)
# Fails when name is updated.
os.rename(orignal_nzb, renamed_nzb)
self.nzb = 'files/%(1)s_%(2)s.nzb' % {'1': self.pk, '2': self.name_slug}
super(File, self).save()
我想问的是,当上传的文件没有重新上传时,是否有人知道如何重命名上传的文件?这是它似乎被锁定/正在使用的唯一时间。
更新
Tyler的方法正在运行,除非上传新文件时主键不可用,并且下面的技巧会引发错误。
if not instance.pk:
instance.save()
错误:
maximum recursion depth exceeded while calling a Python object
有没有办法获取主键?
答案 0 :(得分:5)
我认为你应该更仔细地看看upload_to字段。这可能比在保存期间重命名更简单。
http://docs.djangoproject.com/en/dev/ref/models/fields/#filefield
这也可以是可调用的,例如a 函数,将被调用 获取上传路径,包括 文件名。这个可调用必须能够 接受两个参数,并返回一个 Unix风格的路径(带正斜杠) 被传递到存储器 系统。这两个论点将是 传递的是:
答案 1 :(得分:3)
我的其他答案已被弃用,请改用:
class File(models.Model):
nzb = models.FileField(upload_to=get_filename)
...
def get_filename(instance, filename):
if not instance.pk:
instance.save()
# Create the name slug.
name_slug = re.sub('[^a-zA-Z0-9]', '-', instance.name).strip('-').lower()
name_slug = re.sub('[-]+', '-', name_slug)
filename = u'filess/%(2)s_%(3)s.nzb' % {'2': instance.pk, '3': name_slug}
return filename
从1.0开始,upload_to
can be callable,在这种情况下,它应该返回文件名,包括路径(相对于MEDIA_ROOT)。
答案 2 :(得分:0)
上传后,您拥有的只是内存中的图像对象,对吗?
您可以将此对象自己保存在您选择的文件夹中,然后手动编辑数据库条目。
你将绕过整个Django ORM,除非我找不到更多的Django方式,否则我不会这样做。