FileSystemStorage не работает, и когда загружены 2 изображения, возвращается ошибка SuspiciousFileOperation - PullRequest
0 голосов
/ 28 июня 2019

У меня ужасная проблема.Я хочу загрузить 2 изображения и получить результат после выполнения большого количества кода.Однако, когда я выбираю путь (на сервере) в отношении того, куда загружать эти файлы, я всегда получаю сообщение об ошибке «SuspiciousFileOperation».

представление API

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)

settings.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

Этот код работал нормально перед переустановкой Django и Python из-за некоторых проблем с тензорным потоком, но переустановил все необходимые пакеты.

СпасибоВам за помощь!

Версия Django: 2.2.2 Версия Python: 3.6.7 (64-бит)

1 Ответ

0 голосов
/ 29 июня 2019

слишком долго для комментария

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 и, возможно, оно должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...