Я пытаюсь реализовать загрузку и обработку изображений в моем проекте Django. Проблема с путем для ImageField
:
Вариант 1.
Если я использую путь относительно папки media
, то image.url
приятно возвращает /media/img_name.jpg
, и Django правильно обрабатывает изображения. Но я не могу использовать image.width
свойство, это приводит к ошибке:
SuspiciousFileOperation
Объединенный путь (/user_test/3d55d527-109d-4a07-b0f6-4de0304d41f6.jpg) находится вне компонента базового пути (/ Users / Aivan / Desktop / Code / MyProject / media)
Вариант 2.
Если я использую полный путь, я могу легко получить доступ к свойству image.width
. Но image.url
возвращает полный путь, добавленный в папку media
: http://127.0.0.1:8000/media/Users/Aivan/Desktop/Code/MyProject/media/user_test/8f3219cd-0333-4488-9d29-2c5506707afb.jpg
Вопрос:
Что я должен сделать для правильного доступа к image.url
и image.width
?
Конечно, я всегда могу установить полный путь и добавить сохранить относительный путь в некоторых CharField
или добавить собственный метод для извлечения относительного URL, но, вероятно, такие решения плохие.
Полагаю, это потому, что Django использует относительные пути для медиа-файлов, но для работы с изображениями он использует Pillow, которому нужны полные пути ... Может быть, это ошибка?
Мой класс картинок:
def path_user_photo(instance, filename):
return 'user_{0}'.format(instance.account.user.username)
class Photo(models.Model):
image = models.ImageField(upload_to=path_user_photo)
name = models.CharField(max_length=32, unique=True)
И это статический метод загрузки изображений:
@classmethod
def create_file(cls, fl, user, written_name, ext):
folder = '/user_{0}'.format(user.username)
realname = '/' + str(uuid.uuid4()) + '.' + ext
write_path = settings.MEDIA_ROOT + folder
# Create directory if it doesn't exist
if not os.path.exists(write_path):
os.makedirs(write_path)
# Write data
write_path = write_path + realname
with open(write_path, 'wb+') as destination:
for chunk in fl.chunks():
destination.write(chunk)
res = cls()
# Option 1. Relative path
res.image = folder + realname
# Option 2. Full path
res.image = write_path
res.name = written_name
res.save()
return res
Который я вызываю из вида:
Photo.create_file(
# the file
request.FILES['file_img'],
# current user
request.user,
# written name
request.POST['written_name'],
# real file extension
file.name.split('.')[-1]
)