Django框架+文件上传+API调用

干货内容

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下方法显示出网页的效果。
我们要在这里要做最重要的三个事情:

  1. 根据Get、Post请求显示网页
  2. 上传文件
  3. 调用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的高并发以备急需。

~ 看完点赞再走 ~
文章如有错误和疏漏,请及时联系我,谢谢!

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值