Upload files by Django(Part.1--without Models, Forms, ModelForm)

Django上传文件(Part.1)

这几天一直因为这个问题捣鼓了半天,各种问题都出来了。因为太多了而且最后也解决的,于是就只写一个最后总结出来的方法吧。而且因为问题太多,就把写的时候能想到的遇到的问题顺便就列出来。

只演示上传文件这一单一功能,所以就新建一个项目,一边做一边记录下来。

Ps.在windows系统下

不使用models和forms进行上传(自定义上传文件/图片)

需求:最终创建两个页面,一个是上传主页面,一个是上传结果页面,结果页面分为上传成功和上传失败,两个结果页面都可以再次继续上传。上传的文件保存在与manage.py存在目录下的media/upload文件夹内。

  1. 新建项目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
  1. 然后在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')),//添加
]
  1. 在upload文件中创建urls.py文件,并配置:
from django.urls import path
from . import views

urlpatterns = [
   path('index/',views.index,name='index'),
   path('result/',views.result,name='result')
]
  1. 填写视图方法
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":'上传文件失败!'})
  1. 创建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%}
  1. 到此结束,列举一下最后的项目结构
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 makemigrationspython manage.py migrate),但是强迫症忍不了红色的提示😳