72👍
Django Documentation is always good place to start
class ModelWithImage(models.Model):
image = models.ImageField(
upload_to='images',
)
UPDATED
So this script works.
- Loop over images to download
- Download image
- Save to temp file
- Apply to model
- Save model
.
import requests
import tempfile
from django.core import files
# List of images to download
image_urls = [
'http://i.thegrindstone.com/wp-content/uploads/2013/01/how-to-get-awesome-back.jpg',
]
for image_url in image_urls:
# Stream the image from the url
response = requests.get(image_url, stream=True)
# Was the request OK?
if response.status_code != requests.codes.ok:
# Nope, error handling, skip file etc etc etc
continue
# 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 response.iter_content(1024 * 8):
# If no more file then stop
if not block:
break
# Write image block to temporary file
lf.write(block)
# Create the model you want to save the image to
image = Image()
# Save the temporary image to the model#
# This saves the model so be sure that it is valid
image.image.save(file_name, files.File(lf))
Some reference links:
37👍
If you want to save downloaded images without saving them to disk first (without using NamedTemporaryFile
etc) then there’s an easy way to do that.
This will be slightly quicker than downloading the file and writing it to disk as it is all done in memory. Note that this example is written for Python 3 – the process is similar in Python 2 but slightly different.
from django.core import files
from io import BytesIO
import requests
url = "https://example.com/image.jpg"
resp = requests.get(url)
if resp.status_code != requests.codes.ok:
# Error handling here
fp = BytesIO()
fp.write(resp.content)
file_name = url.split("/")[-1] # There's probably a better way of doing this but this is just a quick example
your_model.image_field.save(file_name, files.File(fp))
Where your_model
is an instance of the model you’d like to save to and .image_field
is the name of the ImageField
.
See the documentation for io for more info.
- [Django]-What is the best approach to change primary keys in an existing Django app?
- [Django]-Django admin – make all fields readonly
- [Django]-Django nested transactions – “with transaction.atomic()”
5👍
# this is my solution
from django.core import files
from django.core.files.base import ContentFile
import requests
from .models import MyModel
def download_img():
r = requests.get("remote_file_url", allow_redirects=True)
filename = "remote_file_url".split("/")[-1]
my_model = MyModel(
file=files.File(ContentFile(r.content), filename)
)
my_model.save()
return
- [Django]-Django character set with MySQL weirdness
- [Django]-How to chcek if a variable is "False" in Django templates?
- [Django]-Getting a count of objects in a queryset in Django
2👍
As an example of what I think you’re asking:
In forms.py:
imgfile = forms.ImageField(label = 'Choose your image', help_text = 'The image should be cool.')
In models.py:
imgfile = models.ImageField(upload_to='images/%m/%d')
So there will be a POST request from the user (when the user completes the form). That request will contain basically a dictionary of data. The dictionary holds the submitted files. To focus the request on the file from the field (in our case, an ImageField), you would use:
request.FILES['imgfield']
You would use that when you construct the model object (instantiating your model class):
newPic = ImageModel(imgfile = request.FILES['imgfile'])
To save that the simple way, you’d just use the save() method bestowed upon your object (because Django is that awesome):
if form.is_valid():
newPic = Pic(imgfile = request.FILES['imgfile'])
newPic.save()
Your image will be stored, by default, to the directory you indicate for MEDIA_ROOT in settings.py.
Accessing the image in the template:
<img src="{{ MEDIA_URL }}{{ image.imgfile.name }}"></img>
The urls can be tricky, but here’s a basic example of a simple url pattern to call the stored images:
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
)
I hope it helps.
- [Django]-Django class-based views with inline model-form or formset
- [Django]-Celery Flower Security in Production
- [Django]-How to customize the auth.User Admin page in Django CRUD?
1👍
Similar to @boltsfrombluesky’s answer above you can do this in Python 3 without any external dependencies like so:
from os.path import basename
import urllib.request
from urllib.parse import urlparse
import tempfile
from django.core.files.base import File
def handle_upload_url_file(url, obj):
img_temp = tempfile.NamedTemporaryFile(delete=True)
req = urllib.request.Request(
url, data=None,
headers={
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'
}
)
with urllib.request.urlopen(req) as response:
img_temp.write(response.read())
img_temp.flush()
filename = basename(urlparse(url).path)
result = obj.image.save(filename, File(img_temp))
img_temp.close()
return result
- [Django]-How do I output HTML in a message in the new Django messages framework?
- [Django]-How to get GET request values in Django?
- [Django]-Save base64 image in django file field
0👍
Try doing it this way instead of assigning path to the image…
import urllib2
from django.core.files.temp import NamedTemporaryFile
def handle_upload_url_file(url):
img_temp = NamedTemporaryFile()
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20120427 Firefox/15.0a1')]
img_temp.write(opener.open(url).read())
img_temp.flush()
return img_temp
use the above function like this..
new_image = images_data()
#rest of the data in new_image and then do this.
new_image.image.save(slug_filename,File(handle_upload_url_file(url)))
#here slug_filename is just filename that you want to save the file with.
- [Django]-How to perform filtering with a Django JSONField?
- [Django]-What is more efficient .objects.filter().exists() or get() wrapped on a try
- [Django]-Django: multiple models in one template using forms
0👍
In case you are saving image by overriding models’ save method to modify the name of file and struggling with random invalid filename(like me) in django. You can follow up below code (Copied from Accepted answer):
lf = tempfile.NamedTemporaryFile()
for block in response.iter_content(1024*8):
if not block:
break
lf.write(block)
lf.name = name. # Set your custom file name here
dc = ImageFile(file=files.File(lf))
dc.file.save()
I have configured my storage with django-storages, in order to directly upload media content to s3. For some reasons I wasn’t able to replace file name. After some R&D it worked.
Note: I have used FileField in the model, hence few line of code is not needed
- [Django]-OSError: [Errno 18] Invalid cross-device link
- [Django]-Get protocol + host name from URL
- [Django]-Django or Django Rest Framework
-2👍
def qrcodesave(request):
import urllib2;
url ="http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=s&chld=H|0";
opener = urllib2.urlopen(url);
mimetype = "application/octet-stream"
response = HttpResponse(opener.read(), mimetype=mimetype)
response["Content-Disposition"]= "attachment; filename=aktel.png"
return response
- [Django]-Django test RequestFactory vs Client
- [Django]-How do I add a custom column with a hyperlink in the django admin interface?
- [Django]-Form field description in django admin