Django从url保存图像并与ImageField连接

时间:2013-05-05 03:55:16

标签: django django-models

我在models.py

class Item(models.Model):
    image_file = models.ImageField(upload_to='images')
    image_url = models.URLField()

我希望django自动下载并在本地保存来自image_url的图片,并将其与image_file“连接”

应如何行动:

  1. 我粘贴https://docs.djangoproject.com/s/img/site/hdr_logo.gif 进入管理员
  2. 中的image_url字段
  3. 点击“保存”
  4. 在模板中写<img src="{{ item.image_file.url }}">。表明 来自我的服务器的图片,而不是djangoproject.com
  5. 我尝试了什么:

    我已覆盖save类的Item方法。我通过urllib在本地保存了图片,但我仍然坚持要将此保存的图片与image_file字段

    连接起来

4 个答案:

答案 0 :(得分:36)

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

答案 1 :(得分:5)

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错误。

由于f字符串,它仅适用于python 3.6 +。

检查此链接:https://twigstechtips.blogspot.com/2012/04/django-programmatically-saving-image.html

答案 2 :(得分: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()

从这里开始:http://stackoverflow.com/questions/17960942/attributeerror-module-object-has-no-attribute-urlretrieve

答案 3 :(得分:1)

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_url”时会自动保存“ image_file”