Django2:提交blob并将其存储为图像文件
在阅读了教程之后,我做了一些Django项目,但我绝对不是Django方面的专家 我正在尝试拍摄当前页面的截图并将其存储(如果不存在的话) 为了实现这一目标,我们需要做几件事:Django2:提交blob并将其存储为图像文件,django,django-models,django-views,blob,Django,Django Models,Django Views,Blob,在阅读了教程之后,我做了一些Django项目,但我绝对不是Django方面的专家 我正在尝试拍摄当前页面的截图并将其存储(如果不存在的话) 为了实现这一目标,我们需要做几件事: 函数获取当前页面的屏幕截图 函数将此图像异步发布到应存储它的视图 存储已发布图像的视图 但是,屏幕截图函数会导致Blob,我在获取Django视图以正确处理此问题时遇到问题 此处提供了一个演示项目: 截图功能 const屏幕截图=(函数(){ 函数urlsToAbsolute(节点列表){ 如果(!节点列表长度){ 返回
const屏幕截图=(函数(){
函数urlsToAbsolute(节点列表){
如果(!节点列表长度){
返回[];
}
var attrName='href';
if(nodeList[0]。\uuuu proto\uuuu===HTMLImageElement.prototype
||节点列表[0]。uuu proto_uuu==HTMLScriptElement.prototype){
attrName='src';
}
nodeList=[].map.call(nodeList,function(el,i){
var attr=el.getAttribute(attrName);
如果(!attr){
返回;
}
var absURL=/^(https?|数据):/i.test(attr);
if(absURL){
返回el;
}否则{
返回el;
}
});
返回节点列表;
}
函数addOnPageLoad_u382;(){
window.addEventListener('DOMContentLoaded',函数(e){
var scrollX=document.documentElement.dataset.scrollX | | 0;
var scrollY=document.documentElement.dataset.scrollY | | 0;
scrollTo(scrollX,scrollY);
});
}
函数capturePage(){
urlsToAbsolute(document.images);
urlsToAbsolute(document.queryselectoral(“link[rel='stylesheet']”);
var屏幕截图=document.documentElement.cloneNode(true);
var b=document.createElement('base');
b、 href=document.location.protocol+'/'+location.host;
var head=screenshot.querySelector('head');
头。插入前(b,头。第一个孩子);
screenshot.style.pointerEvents='none';
screenshot.style.overflow='hidden';
screenshot.style.webkitUserSelect='none';
screenshot.style.mozzuserselect='none';
screenshot.style.msUserSelect='none';
screenshot.style.oUserSelect='none';
screenshot.style.userSelect='none';
screenshot.dataset.scrollX=window.scrollX;
screenshot.dataset.scrollY=window.scrollY;
var script=document.createElement('script');
script.textContent='('+addOnPageLoad_uz.toString()+')();';
screenshot.querySelector('body').appendChild(脚本);
var blob=新blob([screenshot.outerHTML]{
键入:“text/html”
});
返回斑点;
}
返回捕获页面
})()
用于异步post Blob的函数
函数setupAjaxWithCSRFToken(){
//使用jQuery
var csrftoken=jQuery(“[name=csrfmiddlewaretoken]”)。val();
函数csrfSafeMethod(方法){
//这些HTTP方法不需要CSRF保护
返回(/^(获取|头|选项|跟踪)$/.test(方法));
}
//设置csrf头
$.ajaxSetup({
发送前:功能(xhr、设置){
如果(!csrfSafeMethod(settings.type)&&!this.crossDomain){
setRequestHeader(“X-CSRFToken”,CSRFToken);
}
}
});
}
函数asyncSubmitBlob(url,blob){
var fd=新FormData();
fd.append('image',blob);
$.ajax({
url:url,
类型:“POST”,
数据:fd,
contentType:false,
processData:false,
成功:函数(响应){console.log(响应)},
错误:函数(数据){console.log(数据)}
})
}
因此,要提交当前页面的屏幕截图:
setupAjaxWithCSRFToken()
const page=window.location.pathname;
const blob_url=“{%url”我的应用程序:post_blob''替换“%”。替换(/REPLACE/,page='/'?'':page)
asyncSubmitBlob(blob_url,屏幕截图())
查看以存储已发布的blob图像
url.py
型号.py
但我似乎无法忠实地捕捉和找回这个斑点
许多存储blob的S.O.问题使用带有import base64
的模型方法对blob进行编码和解码。甚至有人建议使用二进制字段
。然而,Django的文档明确指出,BinaryField
并不能替代静态文件的处理
那么我怎样才能做到这一点呢
我发现S.O.的帖子有助于实现这一目标
text/html
,而不是图像var blob=newblob([screenshot.outerHTML],{type:'text/html'})代码>@HåkenLid嗯,这是html节点的文本…为什么要使用blob作为文本?可以使用将站点渲染到客户端和图像客户端。请注意,生成的屏幕截图可能与浏览器中的屏幕截图有所不同。@HåkenLid当我尝试它时,它只截取了适合浏览器视图的屏幕截图(不是溢出),我希望溢出。也许这已经改变了。。。
...
from django.urls import include, path
...
app_name='my-app'
url_patterns=[
...
path('post_blob/', views.post_blob, {'page':'/'},name='post_blob'),
path('post_blob/<page>', views.post_blob,name='post_blob'),
...
]
from .models import PageBlob
...
def post_blob(request, page):
if request.FILES: # save screenshot of specified page
try:
pb = PageBlob.objects.all().filter(page=page))
if not pb.count():
pb = PageBlob()
pb.page = page
pb.blob = request.FILES['image']
pb.save()
return HttpResponse('Blob Submitted')
except:
return HttpResponse('[App::my-app]\tError when requesting page_image({page})'.format(page=page))
else: # return screenshot of requested page
try:
# get objects storing screenshot for requested page
pb = PageBlob.objects.all().filter(page=page)
# if one exists
if pb.count():
pb = pb[0]
## this just returns the string literal "blob"
return HttpResponse(str(pb.blob))
return HttpResponse('[App::my-app]\tNo blob for {page}'.format(page=page))
except:
return HttpResponse('[App::my-app]\tError when trying to retrieve blob for {page}'.format(page=page))
return HttpResponse('Another response')
class PageBlob(models.Model):
page = models.CharField(max_length=500)
blob = models.TextField(db_column='data', blank=True)