MENU

Python框架Django上传文件的简单案例分享

March 8, 2021 • Read: 7073 • 默认分类

因为今年参加了中国软件杯, 选择的项目为http://cnsoftbei.com/plus/view.php?aid=581
其中的一个要求为:

  • 数据源接入:支持对接PostgreSQL数据仓库(如Greenplum、EDB等),支持本地上传csv/xlsx文件;

百度到的代码都跟屎一样, 自己琢磨了一下, 研究出了一个比较简洁的文件上传案例

首先, 为了上传文件, 我们肯定需要在HTML中写一个form, 然后form里又会有一个action, 我们就先处理这个action
为了完成这个文章的内容, 请你自己按照Django的文档, 创建一个APP, 然后在APP内操作

首先, 既然我们需要这个action, 就要在Django的APP中的urls创建一个path, 用这个path对应的函数, 来处理这个上传的操作
Django创建的新APP中默认不自带这个urls.py文件, 如果你没有, 可以自行创建一个, 然后向内输入如下代码:

from django.urls import path,include
from django.conf.urls import url
from django.conf import settings
from django.conf.urls.static import static

from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('upload/', views.upload, name='upload'),
    path('upload_csv_process/', views.upload_csv_process, name='upload_csv_process'),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

其中的urlpatterns, 是用来配置这个APP的路由, 这里我的目录结构为根目录是首页, upload是上传页面, uplaod_csv_process也是上传页面, 页面内容相同, 但是upload_csv_process调用的是文件上传的函数, 这个函数写在了views.py中, 在上面通过from . import views引入了这个函数

其中的if settings.DEBUG:也很重要, 先写进去, 后面说为什么

接下来我们先不用去管views中写了什么, 先来处理一下HTML部分的内容, 这部分其实很简单
我们只需要一个form, 一个input type='file', 一个submit

<form method='POST' action='/upload_csv_process' enctype="multipart/form-data">
<!-- 其中的action的值为你在urls.py写的处理上传路径的地址, enctype为Django上传文件必有得参数, 不必深究, 带着就行 -->
    <input type='file' name='upload'>
    <button type='submit'>上传</button>
</form>

OK, HTML的部分只需要这些就足够了, 接下来我们去views.py文件中, 去处理HTML发出的POST请求
我们在下面新写一个函数, 函数名就是path('upload/', views.upload_csv_process, name='upload_csv_process')中的第二个参数views.后面的东西, 代码如下:

# 首先需要引入Django的这个包, 用于保存文件
from django.core.files.storage import default_storage

def upload_csv_process(request):
    # 判断接收到的请求是否为POST并且存在文件
    if request.method == 'POST' and request.FILES:
        # 这里FILES后面的upload是HTML代码中type='file'标签的name值
        file_name = request.FILES['upload'].name
        
        if file_name[-3:] == 'jpg' or file_name[-3:] == 'png':
            uploaded_files = request.FILES['upload']
            name = default_storage.save(file_name, uploaded_files)
            return render(request, 'upload.html', {'status': '上传成功!'})
        else:
            return render(request, 'upload.html', {'status': '上传文件的格式必须为jpg或者png!'})
    # 如果没有接收到文件
    elif not request.FILES:
        return render(request, 'upload.html', {'status': '没有选择文件!'})
    # 这里的return是这个页面的默认页面, 即没有任何操作, 就来到了这个页面, 就什么都不做, 把这个upload.html渲染给他看
    return render(request, 'upload.html')

到这里还没有结束, default_storage.save()这个函数, 第一个参数是文件名, 第二个参数是文件本体, 执行它之后会去检查存储路径下有没有相同名字的文件, 如果有相同文件名, 他就会对这个文件名进行处理, 存储之后, 这个函数会讲它真正存储的文件名return回来, 我们这里用name接收

那它把这个文件存哪去了呢? 它存储的路径我们需要自行配置, 它会把文件保存到settings.py中的MEDIA_ROOT值中
首先去Django的settings.py中, 首先配置一下MEDIA_ROOT与MEDIA_URL

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

MEDIA_ROOT中写的是这个文件要保存到哪个目录, MEDIA_URL中存的是使用什么url, 能访问到这个资源
那这里我们写的就是保存图片到media文件夹中
如果要访问这个图片资源, 假设我们的域名为localhost, 文件名为test.png, 访问的url就是

http://localhost/media/test.png

中间的media就是MEDIA_URL的值, 而我们在urls.py中写的if settings.DEBUG:, 就是让保存函数能知道这个路径是什么

希望这篇文章能帮助到你

Last Modified: September 17, 2023
Leave a Comment

8 Comments
  1. 学习了

  2. rantrism rantrism

    您好~我是腾讯云+社区的运营,关注了您分享的技术文章,觉得内容很棒,我们诚挚邀请您加入腾讯云自媒体分享计划。完整福利和申请地址请见:https://cloud.tencent.com/developer/support-plan
    作者申请此计划后将作者的文章进行搬迁同步到社区的专栏下,你只需要简单填写一下表单申请即可,我们会给作者提供包括流量、云服务器等,另外还有些周边礼物。

  3. dscz dscz

    礼品窝:礼品真实代发、多种类礼品自由选择、海量发件仓,价格0.8元/单。http://www.lpwo.cn

  4. 感谢分享 赞一个

  5. 一抹多 一抹多

    请博主大人尽快联系我 @(花心)@(花心)

    1. @一抹多加我QQ,1565481748