Django сохраняет изображение с URL-адреса и соединяется с ImageField - программирование
Подтвердить что ты не робот

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

4b9b3361

Ответ 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'