Django可以在没有FORMS的情况下上传文件吗?
Posted
技术标签:
【中文标题】Django可以在没有FORMS的情况下上传文件吗?【英文标题】:It is possible for Django to upload file without FORMS? 【发布时间】:2017-01-16 00:02:15 【问题描述】:我目前正在使用自定义 html 模板,而不是在我的 Django 应用上使用表单来上传特定路径中的图像。
应用结构
src/
media/
app/
img/
app_name/
templates/
app_name/
app_template.html
__init__.py
admin.py
apps.py
models.py
tests.py
urls.py
views.py
proj_name/
__init__.py
settings.py
urls.py
wsgi.py
manage.py
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
models.py
class Document(models.Model):
doc_file = models.FileField(upload_to='app/img')
views.py
def app_save(request):
if request.method == 'POST':
newdoc = Document(doc_file=request.FILES.get('myfile'))
newdoc.save()
app_template.html
<form id="myform" method="POST" action="% url 'my_app:save' %"
enctype="multipart/form-data">
<input type="file" name="myfile">
<input type="submit">
</form>
#结果
提交表单后,我没有任何内部服务器错误,也没有 python 回溯。但是app/img
路径中没有上传图片,在我的数据库中,由于newdoc.save()
查询,我插入了一条空白记录。
可以在没有表单的情况下进行文件管理吗?
#更新
我在forms.py
添加了这个
class UploadFileForm(forms.Form):
file = forms.FileField()
并将我的 app_template.html 更新为:
<form id="myform" method="POST" action="% url 'my_app:save' %"
enctype="multipart/form-data">
form.file
<input type="submit">
</form>
那么我想在views.py
中加入加载app_template.html的功能:
def index(request):
form = UploadFileForm()
return render(request, 'app_name/app_template.html', 'form': form )
并且还将app_save()
函数更新为:
def app_save(request):
form = UploadFileForm(request.POST, request.FILES)
if request.method == 'POST':
if form.is_valid():
newdoc = Document(doc_file=request.FILES.get('file')) # note 'file' is the name of input file of a form.
newdoc.save()
现在的问题是
在应用程序中没有发现错误,但没有使用上传的图像文件创建media/app/img
路径。什么地方出了错?我想我在这里漏掉了一些东西。
【问题讨论】:
您在寻找<MEDIA_ROOT>/app/img
中的文件吗?
哦,是的,先生,这是media/app/img
,我更新了应用程序结构
upload_to
始终相对于MEDIA_ROOT
。至少如果你使用FileSystemStorage
。
重要说明:您在表单提交时不使用 javascript 处理程序吗?
@SergeyGornostaev 哦,我使用 jquery onsubmit
先生并使用 $.ajax
将数据传递到服务器
【参考方案1】:
您的后端代码很好。问题出在前端。您不能像其他字段一样使用 jQuery.ajax 提交文件输入。使用FormData:
$('#myform').submit(function(event)
if(window.FormData !== undefined)
event.preventDefault();
var formData = new FormData(this);
var xhr = new XMLHttpRequest();
xhr.open('POST', $(this).attr('action'), true);
xhr.setRequestHeader('X-REQUESTED-WITH', 'XMLHttpRequest')
xhr.onreadystatechange = function()
if(xhr.readyState == 4)
if(xhr.status == 200)
result = JSON.parse(xhr.responseText);
// Code for success upload
else
// Code for error
;
xhr.send(formData);
);
【讨论】:
感谢您的帮助,但在您的回答中,我收到了此错误AttributeError: 'NoneType' object has no attribute 'read'
,它指出了 file_data = uploaded_file.read()
。我的 django 版本是 1.10
表示request.FILES.get('myfile')
返回None
。
但我确定它有价值。
print request.FILES.keys()
的输出是什么?
它打印 dict_keys([])
也许这就是它没有返回的原因,但我已经在表单中包含了 enctype="multipart/form-data"
【参考方案2】:
我不明白你为什么不想使用模型表单;它会让事情变得更容易。
但是,如果您真的想在没有人的情况下执行此操作,则需要自己处理实际的上传操作。 documentation 有一个很好的例子来说明你需要做什么;基本上你只需从request.FILES
获取文件并将其保存到你想要的位置。
【讨论】:
我更新了我的帖子,先生,但它似乎不起作用。我想我错过了什么 是的,你做到了。正如我所说,要么使用负责保存的 ModelForm,要么编写一个函数来处理上传。 我在您的链接中找到了带有 FileField 的表单和模型 为什么这个答案会被接受?这不是一个解决方案,也不是对“Django 可以在没有 FORMS 的情况下上传文件吗?”问题的答案【参考方案3】:django.core.files
中有ContentFile
,使用它来将文件保存为模型字段非常方便。
假设您将一个字段声明为FileField
,并且您可能需要创建一个文件并将其保存到该字段的附件中。然后你可以这样做。
from django.core.files.base import ContentFile
from django.db import models
class YourModel(models.Model):
content = models.FileField(upload_to="any_path_or_callable")
...
def save_file(self, content: str):
temp_file = ContentFile(content)
self.content.save(f'self.pk.txt', temp_file)
希望对你有帮助。
谢谢
【讨论】:
以上是关于Django可以在没有FORMS的情况下上传文件吗?的主要内容,如果未能解决你的问题,请参考以下文章
oracle forms 12c我可以在没有客户端安装的情况下在互联网上获取应用程序吗?