我一直在尝试使用Django中的常规CRUD操作上传一些文件。这些文件通常是在项目的媒体目录中上传的,而通常是上传的,当我尝试从管理区域上传文件时,它是在预期的目录中上传的。内部媒体/简历。
我已经定义了数据库的模型,还定义了媒体根并将其也添加到urlpatterns变量中。当我尝试从管理员视图上传文件时,一切似乎都还可以,并且工作正常,但是当我尝试正常上传文件时,文件直接上传到媒体目录中,而不是media / cv中。
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'home',
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
项目级别的urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('home.urls'))
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
models.py
from django.db import models
class Student(models.Model):
cv = models.FileField(upload_to='cv')
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('student/create', views.insert_student,
name='create_student'),
]
views.py
from django.core.files.storage import FileSystemStorage
from django.shortcuts import redirect
from .models import Student
def insert_student(request):
if request.method == 'POST':
cv = request.FILES['cv']
fs = FileSystemStorage(base_url='')
cvname = fs.save(cv.name, cv)
cv = fs.url(cvname)
stud = Student(cv=cv)
stud.save()
return redirect('home')
student_form.html
<form method="post" action="{% url 'create_student' %}"
enctype="multipart/form-data">
{% csrf_token %}
<input name="cv" type="file" />
<input type="submit" value="Submit" />
</form>
我通常从表单上载文件时希望将文件上载到media / cv中,但是文件是在媒体目录中上载的。当我从管理员登录名添加该学生后,该文件将上传到media / cv目录中。
答案 0 :(得分:1)
发生这种情况的原因是因为您没有让模型保存文件,而是使用FileSystemStorage
显式保存了文件。在该代码中,您都没有将目录设置为cv
。
由于您正在使用带有FileField
的模型,因此只需要执行以下操作即可保存文件:
stud = Student(cv=request.FILES['cv'])
stud.save()
这将确保您的文件保存在cv
文件夹内的media
目录中。不过,我会在执行此操作之前先添加一条支票,因为如果request.FILES['cv']
未发布,则会引发KeyError
异常。另外,在保存之前,您甚至都没有检查文件的内容。这是一个很大的安全漏洞,因为任何人都可以通过这种方式上传任何内容,包括包含恶意软件/病毒的文件。