Upload files by Django(Part.2--without ModelForm)

Django上传文件(Part.2)

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

与第一部分一样,创建一个新的项目,然后一边做一边记录,然后想起之前的问题就补充说明。

不使用ModelForm上传文件

  1. 创建项目、应用
    django-admin startproject mysite
    python manage.py startapp show
  2. 配置mysite/settings.py文件
INSTALLED_APPS = [
   "django.contrib.admin",
			...
   'show',
]
MEDIA_ROOT = "D:/Aproject/django-project/mysite/media" #要创建对应文件夹,不过就算忘记创建django也会在上传时自动创建。不过还是建议提前创建,这样对路径更加清楚。这个路径是一个绝对路径。
MEDIA_URL = '/media/'     #创建这个路由之后,django会自动对每个上传的文件分配路由,具体展示请看接着看。
  1. 配置show/urls.py
    思路:最终创建两个页面,一个是上传主页面,一个是上传结果页面,结果页面分为上传成功和上传失败,两个结果页面都可以再次继续上传。上传的文件保存在与manage.py存在目录下的media/show/文件夹内。
from django.urls import path
from . import views
urlpatterns = [
   path("upload/", views.index,name='index'),
   path("result/", views.result,name='result'),
]
  1. 配置forms.py文件和

forms.py文件

from django import forms
class UploadFiles(forms.Form): 
   file = forms.FileField()  
   #django的forms类可以帮助我们验证上传表单中的数据是否符合要求。我们现在只需要上传一个文件,因此只需要配置FileField字段。

自定义的UploadFiles类的属性要和表单中提交的input的name属性相对应,不然在”is_valid()"验证时会失败!!

  1. 配置models.py文件

models.py文件

from django.db import models

class files(models.Model):
   filename = models.CharField(max_length=255)
   documents = models.FileField(upload_to='show')
#配置文件字段,filename用来储存文件名字;documents储存文件对象,后面的upload_to参数用来规定上传文件的储存地址

配置完成之后记得迁移数据库,不然之后运行会报错(python manage.py makemigrationspython manage.py migrate)
5. 配置views.py方法

from django.shortcuts import render
from .forms import UploadFiles
from .models import files

def index(request):
   return render(request,'index.html')

def result(request):
   if request.method == 'POST':
       form = UploadFiles(request.POST,request.FILES) #将表单信息传递给UploadFiles类进行验证
       name = 'file' 
       if form.is_valid(): #验证正确返回True
           filename = request.FILES[name].name
           tempfile = >files(filename=filename,documents=request.FILES[name]) #实例化files类,并传入上传文件信息初始化
           tempfile.save()  #使用django内置的文件类保存,不用自己编写保存步骤
           return render(request,'result.html',{'result':'文件上传成功!'})
       else:
           message = form.errors  #如果UploadFiles类(forms表单)验证错误,会返回错误对象
           return render(request,'result.html',{'result':'文件上传失败!',
           'message':message,
           })
   else:
       return render(request,'result.html',{'result':'文件上传失败!'})
  1. 创建show/templates文件夹,在里面配置index.html和result.html

index.html

<form name="show" action="{% url 'result'%}" >method="POST" enctype ="multipart/form-data">  
   {% csrf_token %}   
   <label for="fileupload" >请选择要上传的文件</label>  
   <input type="file" name="file" id="fileupload"> /*name属性一定要和forms定义的类一样,不然会判断错误*/
   <input type="submit" value="上传">
</form>
{% block result%}  
{%endblock%}

result.html

{% extends 'index.html' %}   

{% block result%}
{{result}}   
{{message}}
{%endblock%}
  1. 最后的项目结构
D:.
│  db.sqlite3
│  manage.py
│
├─media
│  └─show
│          img401.png #尝试上传的结果
│
├─mysite
│  │  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
│
└─show
   │  admin.py
   │  apps.py
   │  forms.py
   │  models.py
   │  tests.py
   │  urls.py
   │  views.py
   │  __init__.py
   │
   ├─migrations
   │  │  0001_initial.py
   │  │  __init__.py
   │  │
   │  └─__pycache__
   │          0001_initial.cpython-39.pyc
   │          __init__.cpython-39.pyc
   │
   ├─templates
   │      index.html
   │      result.html
   │
   └─__pycache__  
           admin.cpython-39.pyc
           apps.cpython-39.pyc
           forms.cpython-39.pyc
           models.cpython-39.pyc
           urls.cpython-39.pyc
           views.cpython-39.pyc
           __init__.cpython-39.pyc

总结

在重新做一遍注意到了之前没有注意到的事情:forms类的属性要和前端的form表单的input的name属性相对应。
在解决问题的时候还有很多的ajax实现方法,但现在js掌握不熟练,因此暂时不去实践,希望我能快一点掌握好实现!