我正在上传文件并在db中存储元数据。部分元数据是文件名本身。然而,在某个地方,文件名似乎没有被保存!我将仅粘贴我认为是代码的相关部分以保持简短。
class UploadFile(models.Model):
...
theFile = models.FileField(upload_to = "Genius/Uploads/", null = True)
filename = models.CharField(max_length = 50, blank = True, null = False)
class UploadFileForm(ModelForm):
class Meta:
model = UploadFile
fields = ('title', 'theFile', 'date_uploaded',) # Don't prompt for filename
def files_upload(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
form.filename = request.FILES['theFile'].name # TODO: sanitize!
# form.filename = 'foo'
form.save()
return HttpResponseRedirect('/files/upload/successful/')
else:
form = UploadFileForm()
return render_to_response('files/upload_file.html', { 'form': form })
我已经检查了request.FILES ['theFile']的名字。之前和之前的名字保存表格后。无论出于何种原因,它都是完整的,但似乎永远不会进入数据库。
答案 0 :(得分:2)
那是因为form.filename
是表单字段,而不是它将保存的值。
你正在寻找这样的东西:
class UploadFileForm(ModelForm):
def save(self, commit=True):
instance = ModelForm.save(self, commit=False)
instance.filename = self.files['theFile'].name
if commit:
instance.save()
return instance
class Meta:
model = UploadFile
fields = ('title', 'theFile', 'date_uploaded',) # Don't prompt for filename
替代解决方案:
upload_file = form.save(commit=False)
upload_file.filename = request.FILES['theFile'].name
upload_file.save()
答案 1 :(得分:1)
不能通过表单上的属性访问表单字段值。因此,设置'form.filename'不会将值保存在文件名字段中。而是在form.save()返回的实例上设置值。
upload_file = form.save(commit=False)
upload_file.filename = filename
upload_file.save()
答案 2 :(得分:0)
我只想补充一点,将来,您可能会尝试避免在模型表单上放置此类业务逻辑。虽然WoLpH's答案是正确的,并且是如何通过ModelForm
处理其他模型实例处理的一个很好的示例,但在Model
,{{Form
处理具有依赖于其他字段数据的字段的特殊情况。 1}}和ModelForm
API通过他们尊重的clean()
方法在官方参考文档的几个地方提到(这里是forms上的一个,尽管同样适用于{{1} }和Model
API)。
在你的情况下,这意味着:
ModelForm
就是这样!如果您在模型字段上正确设置import os
class UploadFile(models.Model):
# ...
def clean(self):
# Field data has already been populated by this point.
# Note that `FieldFile` inherits from `File` and that
# `File.name` is actually the full path to the file
# so we need to get the base path component sans the extension
path, extension = os.path.splitext(self.thefile.file.name)
self.filename = os.path.basename(path)
属性,您会发现可以依靠Django为editable
模型自动生成ModelForm
。这意味着您不必为通用创建,更新视图或模型的UploadFile
定义ModelForm
,而且需要管理的代码行更少!
一般的经验法则是,您是否会考虑重写默认行为是否合理或自包含,尤其是当您在业务逻辑链的远端工作时,否则您可能会感受到意外失败的愤怒。