Python 从django模板中,如何显示存储为二进制字段模型字段的图像?

Python 从django模板中,如何显示存储为二进制字段模型字段的图像?,python,django,Python,Django,在我的django项目中,我正在使用python脚本抓取数据。在遍历pandas数据帧以将所有信息保存在django模型中之前,我临时将所有字段存储在该数据帧中。我能够让它工作的唯一方法是在模型中将png保存为models.BinaryField。我使用html模板在报告中显示模型的字段,但是图像显示为“memory at”,而不是显示图像。如何显示图像 爬虫 # Import Libraries import requests from selenium import webdriver fr

在我的django项目中,我正在使用python脚本抓取数据。在遍历pandas数据帧以将所有信息保存在django模型中之前,我临时将所有字段存储在该数据帧中。我能够让它工作的唯一方法是在模型中将png保存为models.BinaryField。我使用html模板在报告中显示模型的字段,但是图像显示为“memory at”,而不是显示图像。如何显示图像

爬虫

# Import Libraries
import requests
from selenium import webdriver
from lxml import html
import pandas as pd
import numpy as np
from datetime import datetime
import pytz
from selenium.webdriver.chrome.options import Options

def crawl_website(product, xpath_dict):
    # Set up parameters
    base_url = 'https://www.website.com/product/{sku}/sellers'
header = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 \
        (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36'}

product = product
product_name = product.title
map_price = product.map_price
asin = product.asin
sku = product.sku

# Retrieve Webpage
full_url = base_url.format(sku = sku)
time_stamp = pytz.utc.localize(datetime.utcnow())
page = requests.get(full_url,
                   headers = headers)
doc = html.fromstring(page.content)

# Extract Price Field
original_price = doc.xpath(xpath_dict['original_price'])

# Discount
discount = [str(100 * max(0.0, round(1-float(i) / float(map_price),2))) + '%' for i in original_price]

# MAP Violation Field
map_violation = [float(i) < float(map_price) for i in original_price]

# Extract Seller Names
seller_name = doc.xpath(xpath_dict['seller_name'])

# If a violation is found, take a screenshot
screenshot = None
if True in map_violation:
    # Screenshot of Current URL
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options

    chrome_options = Options()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--window-size=1920,1080")

    DRIVER = 'chromedriver'
    driver = webdriver.Chrome(DRIVER, chrome_options=chrome_options)
    driver.get(full_url)
    screenshot = driver.get_screenshot_as_png()
    driver.quit()

# Extract Seller Links
seller_link = doc.xpath(xpath_dict['seller_link'])

# Create DataFrame
total_rows = len(seller_name)
if True in map_violation:
    df = pd.DataFrame({
                    'Product_Name' : np.repeat(product_name, total_rows),
                    'ASIN' : np.repeat(asin, total_rows),
                    'SKU': np.repeat(sku, total_rows),
                    'Time_Stamp': np.repeat(time_stamp, total_rows),
                    'Seller_Name': seller_name,
                    'Seller_URL': seller_link,
                    'MAP_Price' : np.repeat(map_price, total_rows),
                    'Current_Price': original_price,
                    'Discount' : discount,
                    'MAP_Violation' : map_violation,
                    'Screenshot' : np.repeat(screenshot, total_rows)
    })
else:
        df = pd.DataFrame({
                'Product_Name' : np.repeat(product_name, total_rows),
                'ASIN' : np.repeat(asin, total_rows),
                'SKU': np.repeat(sku, total_rows),
                'Time_Stamp': np.repeat(time_stamp, total_rows),
                'Seller_Name': seller_name,
                'Seller_URL': seller_link,
                'MAP_Price' : np.repeat(map_price, total_rows),
                'Current_Price': original_price,
                'Discount' : discount,
                'MAP_Violation' : map_violation
})

return(df)
report.html

<!doctype html>
<html>
<head>
{% load staticfiles %}
<meta charset="utf-8">
<title>Sales Report</title>

</head>
<body>

{% for sp in seller_price %}
Seller Name: {{ sp.seller_id }}
Image: {{ sp.violation_snapshot }}      
{% endfor %}

</body>
</html>

{%load staticfiles%}
销售报告
{卖方价格%中sp的百分比}
卖方名称:{sp.Seller_id}
图像:{sp.U快照}
{%endfor%}

我强烈建议不要使用二进制字段来保存实际文件,但如果您对它有有效的使用,这是我能想到的最好方法

假设您知道django模板过滤器是什么

@register.filter(name='binary_to_image')
def encode_binary_data_to_image(binary):
    return # return your encoded binary, I would suggest base64.encode which is pretty simple
在你的模板里面

<img src = "data:image/png;base64,{{objects.binary_field|binary_to_image}}">
您可以添加或重构代码,将屏幕截图保存到媒体文件夹中,如

screenshot = driver.save_screenshot('/path/to/image/dir/file.name')
所以它会像django.db.models.ImageField一样将其保存到您的映像目录中,这样您就可以像这样从模型中读取它

<img src="{{object.image_field.url}}"></img>

这可能有效。但是我没有办法测试这个

您需要为二进制编码数据生成Base64编码

import base64
encoded = base64.b64encode("BinaryField as ByteArray")
然后确保将sp.u快照返回为base64编码

然后你可以像这样使用它


这是一种比我的建议更好的方法。过滤器更像django,更像pythonic,imhoI希望采纳您的建议,不要将图像文件存储在二进制字段中。我之所以这样做,是因为我不知道如何将图像文件传递到我的views.py,数据保存在模型中。所有其他数据都在一个数据帧中。有什么建议吗?我在上面添加了很多代码,以防对您有所帮助。
<img src="{{object.image_field.url}}"></img>
import base64
encoded = base64.b64encode("BinaryField as ByteArray")