我一直在尝试在 Django 中使用正常的 CRUD 操作上传一些文件。这些文件在正常上传时正在项目的媒体目录中上传,当我尝试从管理区域上传文件时,它正在预期的目录中上传,即。内部媒体/简历。
我已经为数据库定义了模型,还定义了媒体根并将其也添加到 urlpatterns 变量中。当我尝试从管理 View 上传文件时,一切似乎都正常并且工作正常,但是当我尝试正常上传文件时,文件直接上传到媒体目录,而不是媒体/cv。
设置.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)
模型.py
from django.db import models
class Student(models.Model):
cv = models.FileField(upload_to='cv')
网址.py
from django.urls import path
from . import views
urlpatterns = [
path('student/create', views.insert_student,
name='create_student'),
]
View .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')
学生表格.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 目录中。
请您参考如下方法:
发生这种情况的原因是因为您没有让您的模型保存文件,而是使用 FileSystemStorage 显式保存它。在该代码中,您没有将目录设置为 cv。
由于您使用的是带有 FileField 的模型,因此您只需要这样做来保存您的文件:
stud = Student(cv=request.FILES['cv'])
stud.save()
这将确保您的文件保存在 media 文件夹内的 cv 目录中。不过,我会在执行此操作之前添加一个检查,因为如果未发布 request.FILES['cv'] 可能会引发 KeyError 异常。此外,您甚至没有在保存前检查文件的内容。这是一个很大的安全漏洞,因为任何人都可以通过这种方式上传任何内容,包括包含恶意软件/病毒的文件。
