Django сохраняет изображение с URL-адреса и соединяется с ImageField
У меня есть models.py
:
class Item(models.Model):
image_file = models.ImageField(upload_to='images')
image_url = models.URLField()
Я хочу, чтобы django автоматически загружал и локально сохранял изображение из image_url
и "подключался" к нему с помощью image_file
Как это должно действовать:
- Вставить
https://docs.djangoproject.com/s/img/site/hdr_logo.gif
в поле image_url
в admin
- Нажмите "сохранить"
- В шаблонах пишите
<img src="{{ item.image_file.url }}">
. Это показывает
изображение с моего сервера, а не djangoproject.com
Что я пробовал:
Я перезаписал метод save
класса Item
. Я сохранил изображение локально через urllib
, но я застрял на подключении этого сохраненного изображения с полем image_file
Ответы
Ответ 1
from django.core.files import File
import os
class Item(models.Model):
image_file = models.ImageField(upload_to='images')
image_url = models.URLField()
...
def get_remote_image(self):
if self.image_url and not self.image_file:
result = urllib.urlretrieve(self.image_url)
self.image_file.save(
os.path.basename(self.image_url),
File(open(result[0]))
)
self.save()
Вы можете переопределить метод save() по умолчанию для автоматического вызова get_remote_image().
Смотрите: https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods
Ответ 2
from django.db import models
from django.core.files import File
from urllib.request import urlopen
from tempfile import NamedTemporaryFile
class Item(models.Model):
image_file = models.ImageField(upload_to='images')
image_url = models.URLField()
...
def get_remote_image(self):
if self.image_url and not self.image_file:
img_temp = NamedTemporaryFile(delete=True)
img_temp.write(urlopen(self.image_url).read())
img_temp.flush()
self.image_file.save(f"image_{self.pk}", File(img_temp))
self.save()
Это решение позволяет избежать ошибок utf-8, полученных в процессе URL.
Он работает только с питоном 3. 6+ потому что строка f.
Проверьте эту ссылку: https://twigstechtips.blogspot.com/2012/04/django-programmatics-saving-image.html
Ответ 3
Для python3
from django.core.files import File
from urllib import request
import os
class Item(models.Model):
image_file = models.ImageField(upload_to='images')
image_url = models.URLField()
...
def get_remote_image(self):
if self.image_url and not self.image_file:
result = request.urlretrieve(self.image_url)
self.image_file.save(
os.path.basename(self.image_url),
File(open(result[0], 'rb'))
)
self.save()
отсюда: fooobar.com/questions/160425/...
Ответ 4
python3
from django.db import models
from django.core.files import File
from urllib.request import urlopen
from tempfile import NamedTemporaryFile
class Item(models.Model):
image_file = models.ImageField(upload_to='images')
image_url = models.URLField()
def save(self, *args, **kwargs):
if self.image_url and not self.image_file:
img_temp = NamedTemporaryFile(delete=True)
img_temp.write(urlopen(self.image_url).read())
img_temp.flush()
self.image_file.save(f"image_{self.pk}", File(img_temp))
super(Item, self).save(*args, **kwargs)
Это похоже, но с автоматическим сохранением 'image_file', когда добавить 'image_url'