Ожидаемый объект str, bytes или os.PathLike, а не InMemoryUploadedFile

У меня есть метод, чтобы прочитать файл Newick и вернуть строку в среде Django, которая заключается в следующем:

def handle_uploaded_file(f):
    output = " "
    for chunk in f.chunks():
        output += chunk.decode('ascii')
    return output.replace("\n", "").replace("\r", "")


def post(self, request):
    form = HomeForm(request.POST, request.FILES)
    if form.is_valid():
        input = handle_uploaded_file(request.FILES['file'])
        treeGelezen = Tree(input, format=1)
        script, div = mainmain(treeGelezen)
        form = HomeForm()
    args = {'form': form, 'script': script, 'div': div}
    return render(request, self.template_name, args)

Который работает нормально для обычных файлов Newick, но у меня также есть некоторые файлы, которые имеют строку в начале файла. Я пытаюсь сделать другой метод, который проверяет, есть ли перед файлом следующая строка (что имеет место в некоторых файлах): "newick;" и удаляет строку, если найдена. Это работает локально, но я не могу объединить их. Вот как это выглядит локально:

def removeNewick(tree_with_newick):
    for x in tree_with_newick:
        if x.startswith('newick;'):
            print('')
    return x


filepath = "C:\\Users\\msi00\\Desktop\\ncbi-taxanomy.tre"
tree_with_newick = open(filepath)
tree = Tree(newick=removeNewick(tree_with_newick), format=1)

который отлично работает, когда я указываю путь только в python, поэтому я попытался объединить их в Django следующим образом:

def handle_uploaded_file(f):
    tree_with_newick = open(f)
    for x in tree_with_newick:
        if x.startswith('newick;'):
            print('')
    return cutFile(x)


def cutFile(f):
    output = " "
    for chunk in f.chunks():
        output += chunk.decode('ascii')
    return output.replace("\n", "").replace("\r", "")


def post(self, request):
    form = HomeForm(request.POST, request.FILES)
    if form.is_valid():
        input = handle_uploaded_file(request.FILES['file'])
        treeGelezen = Tree(input, format=1)
        script, div = mainmain(treeGelezen)
        form = HomeForm()
    args = {'form': form, 'script': script, 'div': div}
    return render(request, self.template_name, args)

Который не работает, и это дает следующую ошибку:

expected str, bytes or os.PathLike object, not InMemoryUploadedFile

Я работал над этим уже два дня и не мог понять, почему ошибка появляется.

4 ответа

Ошибка происходит потому, что функция handle_uploaded_file(f) пытается открыть уже открытый файл.

Значение request.FILES['file'] это InMemoryUploadedFile и может быть использован как обычный файл. Вам не нужно открывать его снова.

Чтобы исправить, просто удалите строку, которая пытается открыть файл:

def handle_uploaded_file(f):
    for x in f:
        if x.startswith('newick;'):
            print('')
    return cutFile(x)

решение для меня;

      MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

вместо :

      MEDIA_ROOT = [os.path.join(BASE_DIR, 'media')]

в настройках.py

В моем setting.py у меня было

MEDIA_ROOT = os.path.join(BASE_DIR, 'media'),

когда это должно было быть

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

который решил эту ошибку для меня.

Сохраните InMemoryUploadedFile во временный файл.

вы можете сохранить InMemoryUploadedFile во временный файл, а затем прочитать данные из этого файла.

      import tempfile

if input:
    with tempfile.NamedTemporaryFile(delete=False) as temp_file:
        temp_file.write(input.read())
        temp_file.close()

    with open(temp_file.name, 'r') as file:
        image_data = file.read()
Другие вопросы по тегам