Skip to content

Instantly share code, notes, and snippets.

@jerinisready
Created November 12, 2018 09:36
Show Gist options
  • Select an option

  • Save jerinisready/55c78c05f0104a6d45be348dd5935b56 to your computer and use it in GitHub Desktop.

Select an option

Save jerinisready/55c78c05f0104a6d45be348dd5935b56 to your computer and use it in GitHub Desktop.
ImageParser Class is used to parse an image from external url and save it to Django model field
import requests
import tempfile
from django.core import files
def image_url_to_file(image_url):
# Steam the image from the url
request = requests.get(image_url, stream=True)
# Was the request OK?
if request.status_code != requests.codes.ok:
# Nope, error handling, skip file etc etc etc
return
# Get the filename from the url, used for saving later
file_name = image_url.split('/')[-1]
# 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)
# Save the temporary image to the model#
# This saves the model so be sure that is it valid
# getattr(obj, fieldname).save(file_name, files.File(lf))
return file_name, files.File(lf)
from django.db import models
from django.db.models.base import ModelBase
from .image_url_to_file import image_url_to_file
class ImageParserMixin(object):
"""
ImageParser Class is used to parse an image from external url and save it to model field
the fields can be mentioned under meta class as:
/**
* class MyModel(ImageParserMixin, models.Model):
* ...
* ...
* image_field_1 = models.ImageField(...)
* image_field_2 = models.ImageField(...)
* ...
* url_to_image_fields = ['image_field_1', 'image_field_2', ... ]
*
*/
you can call `{image_field_name}_get_from_url(url)` to save an image into the field.
eg:
`image_field_1_get_from_url(url)(url='http://example.com/../.../image_url.png')
In short;
After overriding the model from `ImageParserMixin` add field names to `url_to_image_fields` list.
you can add image to model via '{field_name}_get_from_url(url)'
"""
url_to_image_fields = []
def __init__(self, *args, **kwargs):
url_to_image_fields = getattr(self, 'url_to_image_fields', [])
if url_to_image_fields:
url_to_image_fields = [field for field in url_to_image_fields \
if hasattr(getattr(self, field), '_get_image_dimensions')] # TODO: A better Validation needed
# image_url_to_model
def set_function(field_name):
def image_parser_function(url):
name, file = image_url_to_file(url)
img = getattr(self, field_name, None)
img.save(name, file)
setattr(self, field_name, img)
return image_parser_function
func_name = "%s_get_from_url"
for field in url_to_image_fields:
setattr(self, func_name % field, set_function(field))
delattr(self.__class__, 'url_to_image_fields')
super().__init__(*args, **kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment