2013-04-23 79 views
17

我正在編寫一個Django應用程序,它將獲取特定URL的所有圖像並將它們保存在數據庫中。下載遠程圖像並將其保存到Django模型

但我沒有得到如何在Django中使用ImageField。

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

我打電話download_imgs.py一個視圖中像

 if form.is_valid(): 
       url = form.cleaned_data['url'] 
       spider(url) 
+0

https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ImageField – 2013-04-23 16:11:23

+0

你想將圖像保存在數據庫斑點或圖像路徑 – mossplix 2013-04-23 16:38:29

+0

@ mossplix - 無論哪種方式...但是,如果我保存圖像作爲路徑,那麼我也想在我的服務器上的圖像 – 2013-04-23 16:48:40

回答

26

Django Documentation總是開始

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

修訂

所以這個腳本工作的好地方。

  • 遍歷圖片下載
  • 下載圖像
  • 保存到臨時文件
  • 適用於模擬
  • 保存模型

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

一些參考鏈接:

  1. requests - 「HTTP人類」,我更喜歡這的urllib2
  2. tempfile - 保存temporay文件,而不是磁盤
  3. 的Django的FileField save
+0

我做到了這一點甚至相應地改變了MEDIA_ROOT路徑。現在呢? – 2013-04-23 16:51:19

+0

好的,將圖像存入數據庫或在訪問後會出現問題? – rockingskier 2013-04-23 16:52:07

+0

無法讓我的服務器上的圖像與圖像數據庫 – 2013-04-23 16:52:49

1

作爲我認爲你問的一個例子:

在forms.py:

imgfile = forms.ImageField(label = 'Choose your image', help_text = 'The image should be cool.') 

在models.py:

imgfile = models.ImageField(upload_to='images/%m/%d') 

所以會有來自用戶的POST請求(當用戶完成表格) 。該請求將基本包含一個數據字典。該字典保存提交的文件。要着力從外地文件的請求(在我們的情況下,ImageField的),你可以使用:

request.FILES['imgfield'] 

你會使用,當你構建模型對象(實例化模型類):

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

要保存簡單的方法,你只用在你的對象賦予的save()方法(因爲Django的是,真棒):

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

你的圖像將被存儲在默認情況下,以該目錄您在settings.py中指定MEDIA_ROOT。

模板訪問圖像:

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

的URL可能會非常棘手,但這裏有一個簡單的URL模式調用存儲圖像的一個基本的例子:

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

我希望能幫助到你。

+0

我不想涉及中間的表單,因爲我不是要求用戶輸入圖像。可以,請告訴我在代碼中粘貼問題的錯誤? – 2013-04-23 19:06:14

+0

你聲稱你不知道如何使用ImageField,所以我引導了你。你沒有真正指定你想要做什麼,而你的代碼是模糊的。如果您嘗試以特殊方式保存圖像,則必須修改save()。 – 2013-04-23 19:33:43

+0

對於vauge代碼抱歉...我想要的是這個..我要求用戶輸入一個網址...我將提取此網址的所有圖像,然後我必須將這些提取的網址與其他一些信息一起保存在數據庫中... – 2013-04-23 19:39:00

0

嘗試做這種方式,而不是對圖像設定路徑...

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 

使用上述功能這樣的..

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

你在那裏做的是描述如何強制用戶的瀏覽器下載圖像。 OP想要將圖像保存到數據庫中的「ImageField」中。 – 2017-04-27 06:55:36

0

與上述相類似@ boltsfrombluesky的回答您可以在Python 3中執行此操作,而不需要任何外部依賴項,如下所示:

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 
3

如果您想要保存下載的圖像而不先保存到磁盤(不使用NamedTemporaryFile等),那麼有一個簡單的方法可以做到這一點。

這比下載文件並將其寫入磁盤稍快,因爲它全部在內存中完成。請注意,此示例是爲Python 3編寫的 - 該過程在Python 2中類似,但略有不同。

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

哪裏your_model是模型的實例,你想保存並.image_fieldImageField的名稱。

有關更多信息,請參閱io的文檔。

相關問題