干货内容
1.Django MTV模式介绍
2.Django下实现文件上传功能
3.Django下实现VirusTotal API调用
文章目录
0x0 Django框架介绍
现在有很多的Web框架都是基于MVC的开发模式进行前后端分离开发的,Django其实也很类似,只不过是基于MTV的开发模式的。
这里就简单介绍一下MTV:
- M 表示模型(Model):编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
- T 表示模板 (Template):负责如何把页面(html)展示给用户。
- V 表示视图(View):负责业务逻辑,并在适当时候调用 Model和 Template。
- 除了以上三层之外,还需要一个 URL 分发器,它的作用是将一个个 URL 的页面请求分发给不同的 View 处理,View 再调用相应的 Model 和 Template,MTV 的响应模式如下所示:
1x0 Django工程创建
这里是通过Form形式来进行文件上传的,逻辑为打开主页,点击上传按钮触发action,跳转到fileManagerUpload,下面详细介绍各个模块的实现过程。
1x1 创建初始Django工程
开发环境的IDE为Pycharm,创建新工程时一定要勾选Application name,这样会方便以后增加多个WebApp:
1x2 创建视图文件:views.py
下面是完整的创建工程目录结构:
2x0文件上传以及API调用代码实现
2x1 工程settings.py设置
因为我们要实现的功能是文件上传,那么我们就一定要确认文件上传后的绝对路径是什么,这时候就要在settings.py下设置好路径。
一定要注意!:windows开发时,路径要配双斜杠 \ \
- settings.py
BASE_DIR = Path(__file__).resolve().parent.parent
MEDIA_URL="media/"
MEDIA_ROOT = os.path.join('E:\\Project\\202104\\djangoProject\\djangoProject', 'media')
2x2 全局路由以及WebApp路由配置
urls.py是用来配置网页调用逻辑的,一般来说一个WebApp初始都是有一个主页的‘Index.html’,但在遇到多个WebApp同事存在的状况时要统一配置:
- 全局路由urls.py配置
from django.contrib import admin
from django.urls import include,path
urlpatterns = [
path('admin/', admin.site.urls), # Django管理界面
path('', include('Virustotal.urls')), # 主页定向到WebApp下的urls配置
]
- WebApp路由urls.py配置
urlpatterns = [
path('',views.index),
path('fileManagerUpload/',views.fileManagerUpload),
] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
2x3 Index.html设置
这里我把异步显示的Ajax代码注释掉了,有需求做异步网页显示可以参考注释的代码,无需异步显示代码就很简单啦:
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ClairJobs</title>
</head>
<body>
<form enctype="multipart/form-data" action="fileManagerUpload/" method="post">
{% csrf_token %}
<input type="file" name="myfile" id="avatar_file"/>
<br/>
<input type="submit" value="upload">
</form>
{#<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>#}
{#<script>#}
{# $(function () {#}
{#一直使用Ajax上传#}
{# console.log('Ajax上传');#}
{# $("#upload").click(function () {#}
{# var formdata = new FormData();#}
{# formdata.append("fname", $("#fname").val());#}
{# formdata.append("lname", $("#lname").val());#}
{# formdata.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());#}
{# $.ajax({#}
{# url: "/process",#}
{# type: "post",#}
{# data: formdata,#}
{# contentType: false,#}
{# processData: false,#}
{# success: function (data) {#}
{# alert("上传成功!")#}
{# console.log(data)#}
{# document.getElementById("p1").innerHTML=data.status;#}
{# document.getElementById("fname").value=data.data.name;#}
{# document.getElementById("lname").value=data.data.age;#}
{# alert(data.list)#}
{# },#}
{# error: function (data) {#}
{# alert("上传失败!")#}
{# console.log(data)#}
{# }#}
{# })#}
{# })#}
{# });#}
{#</script>#}
</body>
</html>
2x4 视图层views.py配置
这个就是经典的view视图了,在这里我们可以根据自己的需要编写方法,然后通过urls路由,最终实现views下方法显示出网页的效果。
我们要在这里要做最重要的三个事情:
- 根据Get、Post请求显示网页
- 上传文件
- 调用VirusTotal API
- views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse
from django.conf import settings
import os
import requests
import json
def index(request):
return render(request,'index.html')
def fileManagerUpload(request):
# 文件上传
print(request.POST)
print(request.FILES)
if request.method=='GET':
return render(request, 'index.html')
if request.method == 'POST':
myFile = request.FILES.get("myfile", None)
print(myFile)
if not myFile:
return HttpResponse('没有要上传的文件')
destination = open(os.path.join(settings.MEDIA_ROOT, myFile.name), 'wb+')
for chunk in myFile.chunks():
destination.write(chunk)
# 上传完成后,通过requests 调用VirusTotal API
url = '你的API调用网址'
params = {'apikey': '你的APIKEY'}
files = {'file': (myFile.name, open(os.path.join(settings.MEDIA_ROOT, myFile.name), 'rb'))}
responseup = requests.post(url, files=files, params=params)
print(responseup.json())
# 下载报告
url = '你的API调用网址'
params = {'apikey': '你的APIKEY',
'resource': '你的文件Hash值'}
responsedown = requests.get(url, params=params)
destination.close()
print(responsedown.json)
return JsonResponse(responsedown.json(),safe=False) #CSRF Token错误
return HttpResponse('失败')
总结 Go与Python的比较
最开始考虑使用Beego实现VirusTotal 的API调用,奈何Go语言的 ‘net/http’ 有点不会用,折中方法是在Beego下添加CURL库再实现接口的调用,有些麻烦,经过查资料和各种试错总结出:Go生而为并发而来,GO更加类似于Python中的协程,适合作为创建API让别人调用,而Go本身去调用别人的API就不如Python来的方便。虽然在目前的场景下是不怎么需要考虑性能的,但是后续还要多学习一下Go的高并发以备急需。
~ 看完点赞再走 ~
文章如有错误和疏漏,请及时联系我,谢谢!