J'écris une application Django qui récupère toutes les images d'une URL particulière et les enregistre dans la base de données.
Mais je ne comprends pas comment utiliser ImageField dans Django.
Paramètres.py
MEDIA_ROOT = os.path.join(PWD, "../downloads/")
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "htp://media.example.com/"
MEDIA_URL = '/downloads/'
models.py
class images_data(models.Model):
image_id =models.IntegerField()
source_id = models.IntegerField()
image=models.ImageField(upload_to='images',null=True, blank=True)
text_ind=models.NullBooleanField()
prob=models.FloatField()
download_img.py
def spider(site):
PWD = os.path.dirname(os.path.realpath(__file__ ))
#site="http://en.wikipedia.org/wiki/Pune"
hdr= {'User-Agent': 'Mozilla/5.0'}
outfolder=os.path.join(PWD, "../downloads")
#outfolder="/home/mayank/Desktop/dreamport/downloads"
print "MAYANK:"+outfolder
req = urllib2.Request(site,headers=hdr)
page = urllib2.urlopen(req)
soup =bs(page)
tag_image=soup.findAll("img")
count=1;
for image in tag_image:
print "Image: %(src)s" % image
filename = image["src"].split("/")[-1]
outpath = os.path.join(outfolder, filename)
urlretrieve('http:'+image["src"], outpath)
im = img(image_id=count,source_id=1,image=outpath,text_ind=None,prob=0)
im.save()
count=count+1
J'appelle download_imgs.py dans une vue comme
if form.is_valid():
url = form.cleaned_data['url']
spider(url)
Documentation Django est toujours un bon point de départ
class ModelWithImage(models.Model):
image = models.ImageField(
upload_to='images',
)
MIS À JOUR
Donc, ce script fonctionne.
.
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:
# 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
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 request.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 is it valid
image.image.save(file_name, files.File(lf))
Quelques liens de référence:
Si vous souhaitez enregistrer les images téléchargées sans les enregistrer d'abord sur le disque (sans utiliser NamedTemporaryFile
etc.), il existe un moyen simple de le faire.
Cela sera légèrement plus rapide que de télécharger le fichier et de l'écrire sur le disque car tout se fait en mémoire. Notez que cet exemple est écrit pour Python 3 - le processus est similaire à Python 2 mais légèrement différent.
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))
Où your_model
est une instance du modèle que vous souhaitez enregistrer et .image_field
est le nom de ImageField
.
Voir la documentation de io pour plus d’informations.
Comme exemple de ce que je pense que vous demandez:
Dans forms.py:
imgfile = forms.ImageField(label = 'Choose your image', help_text = 'The image should be cool.')
Dans models.py:
imgfile = models.ImageField(upload_to='images/%m/%d')
Donc, il y aura une demande POST de l'utilisateur (lorsque l'utilisateur remplira le formulaire). Cette demande contiendra essentiellement un dictionnaire de données. Le dictionnaire contient les fichiers soumis. Pour concentrer la demande sur le fichier depuis le champ (dans notre cas, un ImageField), vous utiliseriez:
request.FILES['imgfield']
Vous utiliseriez cela lorsque vous construisez l'objet de modèle (instanciant votre classe de modèle):
newPic = ImageModel(imgfile = request.FILES['imgfile'])
Pour sauvegarder cela simplement, utilisez simplement la méthode save () conférée à votre objet (car Django est génial):
if form.is_valid():
newPic = Pic(imgfile = request.FILES['imgfile'])
newPic.save()
Votre image sera stockée, par défaut, dans le répertoire que vous indiquez pour MEDIA_ROOT dans settings.py.
Accéder à l'image dans le modèle:
<img src="{{ MEDIA_URL }}{{ image.imgfile.name }}"></img>
Les URL peuvent être délicates, mais voici un exemple de base d'un modèle d'URL simple pour appeler les images stockées:
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$', 'Django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
)
J'espère que ça aide.
Essayez de le faire de cette façon au lieu d’attribuer un chemin à l’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
utilisez la fonction ci-dessus comme ça ..
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.
Semblable à la réponse de @ boltsfrombluesky ci-dessus, vous pouvez le faire dans Python 3 sans aucune dépendance externe comme celle-ci:
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