为什么文件未在Django模型的指定上传路径中上传,而是从管理员上传时在预期目录中上传

时间:2019-05-20 14:25:03

标签: python django

我一直在尝试使用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目录中。

1 个答案:

答案 0 :(得分:1)

发生这种情况的原因是因为您没有让模型保存文件,而是使用FileSystemStorage显式保存了文件。在该代码中,您都没有将目录设置为cv

由于您正在使用带有FileField的模型,因此只需要执行以下操作即可保存文件:

stud = Student(cv=request.FILES['cv'])
stud.save()

这将确保您的文件保存在cv文件夹内的media目录中。不过,我会在执行此操作之前先添加一条支票,因为如果request.FILES['cv']未发布,则会引发KeyError异常。另外,在保存之前,您甚至都没有检查文件的内容。这是一个很大的安全漏洞,因为任何人都可以通过这种方式上传任何内容,包括包含恶意软件/病毒的文件。

相关问题