我想将文件上传到我的数据库,在上传后导入它并最终将数据导出到我的数据库中。我上传工作正常,但我不确定如何在上传文件后获取文件的绝对路径。我能够打印出文档的名称,但是如果上传了相同的文档名称,则会附加它,但如果我调用form.cleaned_data['document'].name
,仍会显示原始文件名。如何获取绝对文件路径然后调用函数以开始处理此文件?
所以这就是我要做的事情:
models.py
from django.db import models
# Create your models here.
class Document(models.Model):
description = models.CharField(max_length=255, blank=True)
document = models.FileField(upload_to='documents/')
uploaded_at = models.DateTimeField(auto_now_add=True)
views.py
from django.shortcuts import render, redirect
from django.views import View
# Create your views here.
from .forms import DocumentForm
from .models import Document
class FileUpload(View):
def post(self, request):
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
print()
print(form.cleaned_data['document'].name)
form.save()
return redirect('main_db_model:home')
else:
return render(request, 'file_upload_form.html', {
'form': form
})
def get(self, request):
form = DocumentForm()
return render(request, 'file_upload_form.html', {
'form': form
})
forms.py
from django import forms
from .models import Document
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ('description', 'document', )
file_upload_form.html(模板):
{% extends "base.html" %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
{% if saved %}
<strong>Your profile was saved.</strong>
{% endif %}
This is the form page
<p><a href="{% url 'main_db_model:home' %}">Return to home</a></p>
<p>Uploaded files:</p>
<ul>
{% for obj in documents %}
<li>
<a href="{{ obj.document.url }}">{{ obj.document.name }}</a>
<small>(Uploaded at: {{ obj.uploaded_at }})</small>
{{ obj.document.url }}
</li>
{% endfor %}
</ul>
{% endblock %}
答案 0 :(得分:2)
以前,我建议您将此upload_to='documents/'
更改为upload_to='documents/%Y/%m/%d'
,为什么?这可以处理documents/
。
form.cleaned_data['document']
(或request.FILES['document']
)返回UploadedFile
个对象。当然form.cleaned_data['document'].name
应该只返回一个名字。
class FileUpload(View):
def post(self, request):
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
# this `initial_obj` if you need to update before it uploaded.
# such as `initial_obj.user = request.user` if you has fk to `User`,
# if not you can only using `obj = form.save()`
initial_obj = form.save(commit=False)
initial_obj.save()
# return path name from `upload_to='documents/'` in your `models.py` + absolute path of file.
# eg; `documents/filename.csv`
print(initial_obj.document)
# return `MEDIA_URL` + `upload_to` + absolute path of file.
# eg; `/media/documents/filename.csv`
print(initial_obj.document.url)
form.save()
但如果您使用upload_to='documents/%Y/%m/%d'
,
print(initial_obj.document) # `documents/2017/02/29/filename.csv`
print(initial_obj.document.url) # `/media/documents/2017/02/29/filename.csv`
答案 1 :(得分:0)
如果您尝试从实际的 Django 表单中保存文件,这些答案会很有效。但是,也许有人(像我一样)从 REST API 上下文中偶然发现了这个问题。因此,在处理 REST API 文件上传 post 请求的上下文中,以下是在 django==3.2 上对我有用的方法:
int COutputWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDockablePane::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rectDummy;
rectDummy.SetRectEmpty();
// Create User Define tabs window:
int UserTabStyle = AfxGetApp()->GetProfileInt(_T("Settings"), _T("UserTabStyle"), 0); //Get value from registry
// If the key doesn't exist, UserTableStyle will be 0 or FALSE;
if (UserTabStyle != FALSE && UserTabStyle <= 8) { // User selected tab style type
int EnumUserTabStyle = UserTabStyle - 1; // Fix enum if key doesn't exist.
if (!m_wndTabs.Create(static_cast<CMFCTabCtrl::Style>(EnumUserTabStyle), rectDummy, this, 1))
{
TRACE0("Failed to create output tab window\n");
return -1; // fail to create
}
}
else { // Default tabs style if Reg key does not exist i.e. new install/program reset
if (!m_wndTabs.Create(CMFCTabCtrl::STYLE_FLAT, rectDummy, this, 1))
{
TRACE0("Failed to create output tab window\n");
return -1; // fail to create
}
}
所以,fs.path(filename) 实际上返回的是我刚刚上传的文件的绝对路径。例如:在我的情况下,我的应用程序在 debian docker 容器中运行,我的媒体目录是 /vol/web/media 并且我得到类似 /vol/web/media/myfile.jpg 的输出,这正是我想要。