복붙노트

[PYTHON] Django : 이미지 URL에서 ImageField에 이미지 추가

PYTHON

Django : 이미지 URL에서 ImageField에 이미지 추가

제 추악한 영어에 대해 용서해주십시오. ;-)

이 아주 간단한 모델을 상상해보십시오.

class Photo(models.Model):
    image = models.ImageField('Label', upload_to='path/')

장고 관리 사이트에서 손으로가 아닌 이미지 URL에서 사진을 만들고 싶습니다.

나는 이렇게 할 필요가 있다고 생각한다.

from myapp.models import Photo
import urllib

img_url = 'http://www.site.com/image.jpg'
img = urllib.urlopen(img_url)
# Here I need to retrieve the image (as the same way that if I put it in an input from admin site)
photo = Photo.objects.create(image=image)

나에게 말하지 않으면 문제를 잘 설명하기를 바랍니다.

고맙습니다 :)

편집하다 :

이것은 작동하지만 장고 파일로 컨텐트를 변환하는 방법을 모른다.

from urlparse import urlparse
import urllib2
from django.core.files import File

photo = Photo()
img_url = 'http://i.ytimg.com/vi/GPpN5YUNDeI/default.jpg'
name = urlparse(img_url).path.split('/')[-1]
content = urllib2.urlopen(img_url).read()

# problem: content must be an instance of File
photo.image.save(name, content, save=True)

해결법

  1. ==============================

    1.나는이 같은 문제에 대해 http://www.djangosnippets.org/snippets/1890/을 만들었습니다. urllib.urlretrieve는 기본적으로 오류 처리를 수행하지 않으므로 urllib2.urlopen을 사용한다는 점을 제외하고는 위의 대답과 유사합니다. 따라서 필요한 항목 대신 404/500 페이지의 내용을 쉽게 얻을 수 있습니다. 콜백 함수 및 사용자 정의 URLOpener 서브 클래스를 만들 수 있지만 다음과 같이 자신의 임시 파일을 만드는 것이 더 쉽다는 것을 알았습니다.

    나는이 같은 문제에 대해 http://www.djangosnippets.org/snippets/1890/을 만들었습니다. urllib.urlretrieve는 기본적으로 오류 처리를 수행하지 않으므로 urllib2.urlopen을 사용한다는 점을 제외하고는 위의 대답과 유사합니다. 따라서 필요한 항목 대신 404/500 페이지의 내용을 쉽게 얻을 수 있습니다. 콜백 함수 및 사용자 정의 URLOpener 서브 클래스를 만들 수 있지만 다음과 같이 자신의 임시 파일을 만드는 것이 더 쉽다는 것을 알았습니다.

    from django.core.files import File
    from django.core.files.temp import NamedTemporaryFile
    
    img_temp = NamedTemporaryFile(delete=True)
    img_temp.write(urllib2.urlopen(url).read())
    img_temp.flush()
    
    im.file.save(img_filename, File(img_temp))
    
  2. ==============================

    2.

    
    from myapp.models import Photo
    import urllib
    from urlparse import urlparse
    from django.core.files import File
    
    img_url = 'http://www.site.com/image.jpg'
    
    photo = Photo()    # set any other fields, but don't commit to DB (ie. don't save())
    name = urlparse(img_url).path.split('/')[-1]
    content = urllib.urlretrieve(img_url)
    
    # See also: http://docs.djangoproject.com/en/dev/ref/files/file/
    photo.image.save(name, File(open(content[0])), save=True)
    
    
  3. ==============================

    3.ImageField는 문자열 일 뿐이며 MEDIA_ROOT 설정과 관련된 경로입니다. 파일을 저장하기 만하면됩니다. PIL을 사용하여 이미지인지 확인하고 파일 이름으로 필드를 채울 수 있습니다.

    ImageField는 문자열 일 뿐이며 MEDIA_ROOT 설정과 관련된 경로입니다. 파일을 저장하기 만하면됩니다. PIL을 사용하여 이미지인지 확인하고 파일 이름으로 필드를 채울 수 있습니다.

    따라서 urllib.urlopen의 출력을 파일 (미디어 위치 내부)에 저장하고 경로를 수정하여 모델에 저장해야한다는 점이 코드와 다릅니다.

  4. ==============================

    4.Python 3에서이 방법을 사용합니다. Python 2에서 간단한 수정 작업을 수행해야합니다. 검색하는 파일이 작다는 사실을 알고 있습니다. 그렇지 않다면 메모리에 버퍼링하는 대신 파일에 응답을 쓰는 것이 좋습니다.

    Python 3에서이 방법을 사용합니다. Python 2에서 간단한 수정 작업을 수행해야합니다. 검색하는 파일이 작다는 사실을 알고 있습니다. 그렇지 않다면 메모리에 버퍼링하는 대신 파일에 응답을 쓰는 것이 좋습니다.

    BytesIO는 Django가 파일 객체에 대해 seek ()을 호출하고 urlopen 응답이 탐색을 지원하지 않기 때문에 필요합니다. 대신 Django의 ContentFile에 read ()에 의해 반환 된 bytes 객체를 전달할 수 있습니다.

    from io import BytesIO
    from urllib.request import urlopen
    
    from django.core.files import File
    
    
    # url, filename, model_instance assumed to be provided
    response = urlopen(url)
    io = BytesIO(response.read())
    model_instance.image_field.save(filename, File(io))
    
  5. ==============================

    5.Chris Adams와 Stan이 말한 것과 Python 3에서 작동하도록 업데이트 한 것을 결합하여, Request를 설치하면 다음과 같이 할 수 있습니다 :

    Chris Adams와 Stan이 말한 것과 Python 3에서 작동하도록 업데이트 한 것을 결합하여, Request를 설치하면 다음과 같이 할 수 있습니다 :

    from urllib.parse import urlparse
    import requests
    from django.core.files.base import ContentFile
    from myapp.models import Photo
    
    img_url = 'http://www.example.com/image.jpg'
    name = urlparse(img_url).path.split('/')[-1]
    
    photo = Photo() # set any other fields, but don't commit to DB (ie. don't save())
    
    response = requests.get(img_url)
    if response.status_code == 200:
        photo.image.save(name, ContentFile(response.content), save=True)
    

    Django의 ContentFile 문서 및 요청의 파일 다운로드 예제에서 더 관련성이 높은 문서.

  6. ==============================

    6.이것이 바로 올바른 방법입니다.

    이것이 바로 올바른 방법입니다.

    class Product(models.Model):
        upload_path = 'media/product'
        image = models.ImageField(upload_to=upload_path, null=True, blank=True)
        image_url = models.URLField(null=True, blank=True)
    
        def save(self, *args, **kwargs):
            if self.image_url:
                import urllib, os
                from urlparse import urlparse
                filename = urlparse(self.image_url).path.split('/')[-1]
                urllib.urlretrieve(self.image_url, os.path.join(file_save_dir, filename))
                self.image = os.path.join(upload_path, filename)
                self.image_url = ''
                super(Product, self).save()
    
  7. ==============================

    7.Django 프로젝트에서 파일 업로드 기능을 사용하려면 먼저 베개를 설치해야합니다.

    Django 프로젝트에서 파일 업로드 기능을 사용하려면 먼저 베개를 설치해야합니다.

    pip install pillow==2.6.1
    

    settings.py에 미디어 파일의 URL을 설정하는 것을 잊지 마십시오.

    MEDIA_ROOT = 'media/'
    

    그런 다음 models.py에 다음 이미지 필드를 추가하십시오.

    userlogo = models.ImageField(upload_to="userlogo/", blank=True, null=True)
    

    이 코드를 작성한 후 다음을 사용하여 모델을 마이그레이션하십시오.

    python manage.py makemigrations
    python manage.py migrate
    

    이제 이미지 필드를 사용하여 이미지 파일을 업로드 할 수 있습니다. 이미지 파일은 YOUR_PROJECT_ROOT / media / userlogo 디렉토리에 업로드됩니다. 'userlogo'폴더를 수동으로 생성 할 필요가 없습니다.

  8. from https://stackoverflow.com/questions/1393202/django-add-image-in-an-imagefield-from-image-url by cc-by-sa and MIT license