Django — сохранение файла Excel в файловое поле модели

#python #django #django-models

#python #django #django-модели

Вопрос:

Я хочу сохранить файл в своем поле excel_file, но у меня есть эта ошибка :
кодек ‘utf-8’ не может декодировать байт 0x9d в позиции 15: недопустимый начальный байт

 
class Product(models.Model):
    excel_file = models.FileField(upload_to='upload', blank=True)
    
    def save(self, *args, **kwargs):
        try : 
            myFile = open('excel_file.xlsx', 'r')
            name = "new_test.xlsx"
            self.excel_file.save(name, File(myFile))
            super().save(*args, **kwargs)

        except Exception as e:
            print(e)




 

Ответ №1:

Вы не открываете свой файл в двоичном режиме, отсюда и ошибка:

 class Product(models.Model):
    excel_file = models.FileField(upload_to='upload', blank=True)
    
    def save(self, *args, **kwargs):
        try :
            #                  binary mode ↓
            with open('excel_file.xlsx', 'rb') as myFile:
                name = 'new_test.xlsx'
                self.excel_file.save(name, File(myFile), save=False)
            super().save(*args, **kwargs)

        except Exception as e:
            print(e) 

Здесь save=False параметр [Django-doc] предотвратит то, что сохранение файла Excel приведет к повторному вызову save метода модели и, таким образом, приведет к бесконечной рекурсии.


Примечание: Пожалуйста, не используйте общий шаблон, за исключением: попробуйте ограничить обработку исключений конкретными исключениями. Другие исключения не должны перехватываться, а обрабатываться потоком кода, который вызвал подпрограмму. Используя except , вы в основном остановите любое исключение, но это часто не очень хорошая идея, поскольку вызывающий, таким образом, предполагает, что вызов выполнен успешно.

Комментарии:

1. Спасибо, но теперь у меня другая ошибка: превышена максимальная глубина рекурсии Фатальная ошибка Python: невозможно восстановить из-за переполнения стека. И это создало папку со многими файлами, а не новый файл Excel с new_test.xlsx имя

2. @alpha: ys, это потому self.excel_file.save , что вызовет save Model конечно.

3. @alpha: и open(...) будет создана копия файла, поскольку позже возможно, что вы хотите обновить файл, и, следовательно, они должны быть независимыми друг от друга.

4. @alpha: вы можете опустить рекурсию с помощью: self.excel_file.save(name, File(myFile), save=False)