如何从URL上传图像

时间:2017-04-09 21:45:21

标签: python django

我有2种方式上传图片。 1是从用户的文件中选择图像,而另一个是通过URL上传图像。

模型

class Post(models.Model):
    ...
    image = models.FileField(null=True, blank=True)
    imageURL = models.URLField(null=True, blank=True)

    def download_file_from_url(self):
        print('DOWNLOAD') #prints "DOWNLOAD"
        # Stream the image from the url
        try:
            request = requests.get(self, stream=True)
        except requests.exceptions.RequestException as e:
            # TODO: log error here
            return None

        if request.status_code != requests.codes.ok:
            # TODO: log error here
            return None

        # Create a temporary file
        lf = tempfile.NamedTemporaryFile()

        # Read the streamed image in sections
        for block in request.iter_content(1024 * 8):

            # If no more file then stop
            if not block:
                break

            # Write image block to temporary file
            lf.write(block)
            return files.File(lf)

HTML

    <input id="id_image" type="file" name="image" /> <!--upload from file-->
    {{ form_post.imageURL|placeholder:"URL" }} <!--url upload-->

从文件上传图片工作正常,用户只需点击输入并选择他们的文件。但是,当用户决定使用URL选项时,我是否会获取该URL字符串并将其设为image字段的值?

视图

    ...
    if form_post.is_valid():
        instance = form_post.save(commit=False)
            if instance.imageURL:
                instance.image = Post.download_file_from_url(instance.imageURL)
                instance.save()

urls.py

...
if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

settings.py

...
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

2 个答案:

答案 0 :(得分:1)

您不能在FileField上放置字符串。它需要是一个文件。但有一个解决方法。您需要从服务器上的URL下载文件,然后将其保存到数据库中。

这是一个可以帮助您的代码:

class CachedImage(models.Model):
    url = models.CharField(max_length=255, unique=True)
    photo = models.ImageField(upload_to=photo_path, blank=True)

    def cache(self):
        """Store image locally if we have a URL"""

        if self.url and not self.photo:
            result = urllib.request.urlretrieve(self.url)
            self.photo.save(
                    os.path.basename(self.url),
                    File(open(result[0]))
                    )
            self.save()

答案 1 :(得分:1)

Python 3兼容方法:

import requests
import tempfile
from django.core import files

def download_file_from_url(url):
    # Stream the image from the url
    try:
        request = requests.get(url, stream=True)
    except requests.exceptions.RequestException as e:
        # TODO: log error here
        return None

    if request.status_code != requests.codes.ok:
        # TODO: log error here
        return None

    # Create a temporary file
    lf = tempfile.NamedTemporaryFile()

    # Read the streamed image in sections
    for block in request.iter_content(1024 * 8):

        # If no more file then stop
        if not block:
            break

        # Write image block to temporary file
        lf.write(block)

    return files.File(lf)
#Do this in your view
if self.url and not self.photo:
       self.photo = download_file_from_url(url)