Upload files by Django(Part.1--without Models, Forms, ModelForm)
Django上传文件(Part.1)
这几天一直因为这个问题捣鼓了半天,各种问题都出来了。因为太多了而且最后也解决的,于是就只写一个最后总结出来的方法吧。而且因为问题太多,就把写的时候能想到的遇到的问题顺便就列出来。
只演示上传文件这一单一功能,所以就新建一个项目,一边做一边记录下来。
Ps.在windows系统下
不使用models和forms进行上传(自定义上传文件/图片)
需求:最终创建两个页面,一个是上传主页面,一个是上传结果页面,结果页面分为上传成功和上传失败,两个结果页面都可以再次继续上传。上传的文件保存在与manage.py存在目录下的media/upload文件夹内。
- 新建项目temptation,并新建app。在有django环境下的windows命令窗口中输入
django-admin startproject temptation
python manage.py startapp upload
生成的项目结构:
D:temptation │ manage.py │ ├─temptation│ │ asgi.py │ │ settings.py │ │ urls.py │ │ wsgi.py │ │ __init__.py │ │ │ └─__pycache__ │ settings.cpython-39.pyc │ __init__.cpython-39.pyc │ └─upload │ admin.py │ apps.py │ models.py │ tests.py │ views.py │ __init__.py │ └─migrations __init__.py
- 然后在temptation/settings.py中
INSTALLED_APPS = [ "django.contrib.admin", ...... 'upload',//添加
Ps. 此时不对TEMPALTES中的DIRS进行配置,这样在之后配置html文件时就可以直接在upload下创建templates文件夹,然后直接将html文件放入。因为不对路径进行配置django会先寻找manage.py所在的文件夹中是否有templates文件夹,然后再在每个app下寻找templates文件夹,直到找到为止。
3. temptation/urls.py中:
from django.contrib import admin from django.urls import path,include//添加 urlpatterns = [ path("admin/", admin.site.urls), path("upload/", include('upload.urls')),//添加 ]
- 在upload文件中创建urls.py文件,并配置:
from django.urls import path from . import views urlpatterns = [ path('index/',views.index,name='index'), path('result/',views.result,name='result') ]
- 填写视图方法
from django.shortcuts import render def index(request): //配置基础页面 return render(request,'index.html') def result(request): if request.method == "POST": file = request.FILES['file'] filename = file.name filepath = "media/upload/" + filename //创建文件保存路径,是一个相对路径,相对于manage.py所在的文件夹 with open(filepath,'wb+') as f: //写入文件 for chunk in file.chunks(): //分块写入文件,避免文件太大占满内存 f.write(chunk) f.close() return render(request,'result.html',{'result':'上传文件成功!'}) else: return render(request,'result.html',{"result":'上传文件失败!'})
- 创建templates文件夹,并创建index.html和result.html页面
index.html
<form name="show" action="{% url 'result'%}" method="POST" enctype ="multipart/form-data"> /*创建form表单*/ /*action表示表单上传至result.html页面,如果action为空那么不会有页面转跳,文件也上传失败。*/ {% csrf_token %} /*django内置的上传用户审查,目前只需要记住上传文件的时候要加上*/ <label for="fileupload" >请选择要上传的文件</label> /*for属性表示将label标签和id为fileupload的input标签关联*/ <input type="file" name="file" id="fileupload"> <input type="submit" value="上传"> </form> {% block result%} /*django的继承模板,用于做出类似于不刷新页面返回结果的效果*/ {%endblock%}
result.html
{% extends 'index.html' %} /*继承index.html模板*/ {% block result%} {{result}} /*显示上传结果*/ {%endblock%}
- 到此结束,列举一下最后的项目结构
D:temptation │ db.sqlite3 │ manage.py │ ├─media │ └─upload │ img401.png │ img402.png │ ├─temptation │ │ asgi.py │ │ settings.py │ │ urls.py │ │ wsgi.py │ │ __init__.py │ │ │ └─__pycache__ │ settings.cpython-39.pyc │ urls.cpython-39.pyc │ wsgi.cpython-39.pyc │ __init__.cpython-39.pyc │ └─upload │ admin.py │ apps.py │ models.py │ tests.py │ urls.py │ views.py │ __init__.py │ ├─migrations │ │ __init__.py │ │ │ └─__pycache__ │ __init__.cpython-39.pyc │ ├─templates │ index.html │ result.html │ └─__pycache__ admin.cpython-39.pyc apps.cpython-39.pyc models.cpython-39.pyc urls.cpython-39.pyc views.cpython-39.pyc __init__.cpython-39.pyc
评价:这种方法最简单,不需要很多其他的配置,文件路径和名字也都可以自定义(比如换成上传时间)。但是缺少对上传文件格式的判断、对表单传来数据的审查、没有存储到数据库不方便管理等。
Ps. 这个项目完全可以不用创建数据库(也就是使用python manage.py makemigrations
和python manage.py migrate
),但是强迫症忍不了红色的提示😳