Skip to main content
 首页 » 编程设计

python之为什么文件没有上传到 Django 模型中指定的上传路径,当从管理员上传时它正在上传到预期的目录

2024年11月24日24kerrycode

我一直在尝试在 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 异常。此外,您甚至没有在保存前检查文件的内容。这是一个很大的安全漏洞,因为任何人都可以通过这种方式上传任何内容,包括包含恶意软件/病毒的文件。