django - FileSystemStorage 不起作用,当上传 2 张图片时,返回 SuspiciousFileOperation 错误
问题描述
我有一个可怕的问题。我想上传 2 张图片并在运行大量代码后得到结果。但是,当我选择(在服务器上)上传这些文件的路径时,我总是会收到“SuspiciousFileOperation”错误。
接口视图
import json
import os
from rest_framework import generics
from rest_framework.response import Response
from rest_framework import permissions
from .ProcessData.FaceRecognition import FaceRecognition
from .ProcessData.OCR import OCR
from .ProcessData.Wanted import Wanted
from identity.models import IdentityCheck
from .serializers import IdentityCheckSerializer
from rest_framework.generics import CreateAPIView
from django.core.files.storage import FileSystemStorage
from django.conf import settings
class IdentityCheckView(CreateAPIView, generics.ListAPIView):
serializer_class = IdentityCheckSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
request = self.request
qs = IdentityCheck.objects.all()
query = self.request.GET.get('q')
if query is not None:
qs = qs.filter(name__icontains=query)
return qs
def save_fss(self, filename, file):
mediaRoot = os.path.join(settings.MEDIA_ROOT, 'media/tmp/')
filename = filename + ".jpg"
fs = FileSystemStorage(location=mediaRoot)
if fs.exists(filename):
os.remove(mediaRoot + filename)
newFile = fs.save(filename, file)
uploaded_file_url = mediaRoot + fs.url(newFile)
return uploaded_file_url
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if(serializer.is_valid()):
data = serializer.validated_data
passPhoto = request.FILES['passengerPhoto']
uploaded_file_url_pass_photo = self.save_fss("passPhoto", passPhoto)
passPassport = request.FILES['passengerPassport']
uploaded_file_url_pass_passport = self.save_fss("passPassport", passPassport)
image = FaceRecognition.imageMatch(uploaded_file_url_pass_photo, uploaded_file_url_pass_passport)
wanted = Wanted.criminalMatch(uploaded_file_url_pass_photo)
passport_json = OCR.passportMatch(uploaded_file_url_pass_passport)
image_json = json.loads(image)
firstName = passport_json['names']
lastName = passport_json['surname']
nationality = passport_json['country']
birthDate = passport_json['date_of_birth']
gender = passport_json['sex']
ableToBoard = (wanted==0) and (int(image_json['match'])==1) and passport_json['valid_expiration_date'] and passport_json['valid_date_of_birth']
serializer.save(agent=self.request.user, firstName=firstName, lastName=lastName, nationality=nationality, birthDate=birthDate, gender=gender, ableToBoard=ableToBoard)
else:
return Response({"image": "-1", "passport": "-1", "wanted": "-1"}, status=500)
return Response({"image": image_json, "passport": passport_json, "wanted": wanted}, status=200)
设置.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DEBUG = True
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.postgres',
'django_postgres_extensions',
'rest_framework',
'corsheaders',
'identity',
'models',
'admincp',
'abnormal',
'language'
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'IBCS.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
...
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.dirname(BASE_DIR)
MEDIA_URL = '/'
from IBCS.restconf.main import *
from IBCS.apps import *
错误显示:
The joined path (C:\Users\Kyoko\Desktop\IBCS\server\media\tmp\passPhoto.jpg) is located outside of the base path component (C:\Users\Kyoko\Desktop\IBCS\server\media\tmp\)
Bad Request: /api/check/
"POST /api/check/ HTTP/1.1" 400 20335
由于一些 tensorflow 问题,此代码在重新安装 Django 和 Python 之前运行良好,但重新安装了所有需要的包。
谢谢您的帮助!
Django 版本:2.2.2 Python 版本:3.6.7(64 位)
解决方案
评论太长了
1
MEDIA_ROOT = os.path.dirname(BASE_DIR)
MEDIA_URL = '/'
...
os.path.join(settings.MEDIA_ROOT, 'media/tmp/')
不,你不应该设置MEDIA_ROOT = BASEDIR
,你应该设置
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'media')
MEDIA_URL = '/media/'
并避免media
在要使用这些文件的任何地方连接。请注意,在 prod 上,您应该为媒体文件选择其他一些根文件夹 - 在项目目录之外。
您还应该设置STATIC_ROOT
未在 settings.py 中配置的内容
2
mediaRoot = os.path.join(settings.MEDIA_ROOT, 'media/tmp/')
mediaRoot + filename
不要path.join
与简单的串联混合。在此示例中,您正在混合\
和/
分隔符(因为您在 Windows 上)。它会起作用,但不是一种好的风格;URL 会失败。在这里 - 总是使用os.path.join
. 注意,它可以有两个以上的参数。
3
uploaded_file_url = mediaRoot + fs.url(newFile)
medirRoot
是一个文件夹,在您的情况下\
用作路径分隔符,而fs.url
它是一个带有/
分隔符的 URL。因此,您不会在此处获得文件的 URL 或完整路径。是的,它应该可以工作,因为它fs.url
会返回部分 URL 并复制文件的部分路径......但是,a)fs 有path
方法 b)如果你上传到常量,为什么你要进行这种连接小路?
4
if fs.exists(filename):
os.remove(mediaRoot + filename)
fs 可以delete()
这样做,不要混合处理文件的方法。请注意,无论何时何人上传文件,您都将始终覆盖文件。
5
您应该显示完整的错误回溯。但是,我的猜测是:您不应该从save_fss
. 尝试返回fs.path()
,MEDIA_ROOT
正确配置,也许它应该可以工作。
推荐阅读
- r - 将分面图减少到一个 ggplot
- elasticsearch - ELASTICSEARCH - 计算具有条件的唯一值
- android - 使用 Apollo 客户端将文件上传到 GraphQL
- mongodb - 使用外部字段值 Mongodb 更新内部数组元素属性
- java - (GXT) 在弹出面板的所有子项中更改注册
- php - 未捕获的 PHP 异常
- c++ - 为什么我会收到此错误:“bool”之前的预期主表达式?
- javascript - 关于 Hyperledger Fabric 的登录注册架构师
- sql - 如果在 Microsoft SQL Server 中未找到任何行,则返回 0
- python - “SQLAlchemy”的实例没有“列”成员