it-swarm.com.de

Laden Sie ein Remote-Image herunter und speichern Sie es in einem Django-Modell

Ich schreibe eine Django-App, die alle Bilder einer bestimmten URL abruft und in der Datenbank speichert.

Aber ich verstehe nicht, wie ich ImageField in Django benutzen kann.

Einstellungen.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

Ich rufe download_imgs.py in einer Ansicht auf

        if form.is_valid():
                url = form.cleaned_data['url']
                spider(url)
22
Mayank Jain

Django-Dokumentation ist immer ein guter Anfang

class ModelWithImage(models.Model):
    image = models.ImageField(
        upload_to='images',
    )

AKTUALISIERT

Das Skript funktioniert also.

  • Bilder zum Herunterladen überarbeiten
  • Bild herunterladen
  • Speichern Sie die temporäre Datei
  • Auf das Modell anwenden
  • Modell speichern

.

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))

Einige Referenzlinks:

  1. Requests - "HTTP für Menschen", ich bevorzuge dies eher als urllib2
  2. tempfile - Temporäre Datei speichern und nicht auf der Festplatte speichern
  3. Django-Dateifeld Speichern
36
rockingskier

Wenn Sie heruntergeladene Bilder speichern möchten, ohne sie zuerst auf der Festplatte zu speichern (ohne NamedTemporaryFile usw.), dann gibt es eine einfache Möglichkeit, dies zu tun.

Dies ist etwas schneller, als die Datei herunterzuladen und auf die Festplatte zu schreiben, da dies alles im Speicher erfolgt. Beachten Sie, dass dieses Beispiel für Python 3 geschrieben wurde. Der Prozess ist in Python 2 ähnlich, jedoch etwas anders.

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))

Dabei ist your_model eine Instanz des Modells, in der Sie speichern möchten, und .image_field ist der Name der ImageField.

Weitere Informationen finden Sie in der Dokumentation zu io .

17
Michael Bates

Als Beispiel für das, was ich denke, fragen Sie:

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')

Es wird also eine POST -Anfrage des Benutzers geben (wenn der Benutzer das Formular ausfüllt). Diese Anfrage enthält im Wesentlichen ein Wörterbuch mit Daten. Das Wörterbuch enthält die eingereichten Dateien. Um die Anfrage aus dem Feld auf die Datei (in unserem Fall ein ImageField) zu fokussieren, verwenden Sie:

request.FILES['imgfield']

Sie würden dies verwenden, wenn Sie das Modellobjekt konstruieren (um Ihre Modellklasse zu instantiieren):

newPic = ImageModel(imgfile = request.FILES['imgfile'])

Um dies auf einfache Weise zu speichern, verwenden Sie einfach die save () -Methode, die Ihrem Objekt zugewiesen wurde (weil Django so fantastisch ist):

if form.is_valid():
    newPic = Pic(imgfile = request.FILES['imgfile'])
    newPic.save()

Ihr Bild wird standardmäßig in dem Verzeichnis gespeichert, das Sie für MEDIA_ROOT in settings.py angeben.

Zugriff auf das Bild in der Vorlage:

<img src="{{ MEDIA_URL }}{{ image.imgfile.name }}"></img>

Die URLs können schwierig sein, aber hier ein einfaches Beispiel für ein einfaches URL-Muster, um die gespeicherten Bilder aufzurufen:

urlpatterns += patterns('',
        url(r'^media/(?P<path>.*)$', 'Django.views.static.serve', {
            'document_root': settings.MEDIA_ROOT,
        }),
   )

Ich hoffe, es hilft.

1
Mr_Spock

Versuchen Sie es auf diese Weise, anstatt dem Bild einen Pfad zuzuweisen ... 

    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

benutze die obige Funktion wie folgt ..

    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.
0

Ähnlich wie oben bei @ boltfrombluesky können Sie dies auch in Python 3 ohne externe Abhängigkeiten tun:

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
0
Hairy Chris