Upload files by Django(Part.2--without ModelForm)
Django上传文件(Part.2)
只演示上传文件这一单一功能,所以就新建一个项目,一边做一边记录下来。在windows系统下
与第一部分一样,创建一个新的项目,然后一边做一边记录,然后想起之前的问题就补充说明。
不使用ModelForm上传文件
- 创建项目、应用
django-admin startproject mysite
python manage.py startapp show
- 配置mysite/settings.py文件
INSTALLED_APPS = [ "django.contrib.admin", ... 'show', ]
MEDIA_ROOT = "D:/Aproject/django-project/mysite/media" #要创建对应文件夹,不过就算忘记创建django也会在上传时自动创建。不过还是建议提前创建,这样对路径更加清楚。这个路径是一个绝对路径。 MEDIA_URL = '/media/' #创建这个路由之后,django会自动对每个上传的文件分配路由,具体展示请看接着看。
- 配置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'), ]
- 配置forms.py文件和
forms.py文件
from django import forms class UploadFiles(forms.Form): file = forms.FileField() #django的forms类可以帮助我们验证上传表单中的数据是否符合要求。我们现在只需要上传一个文件,因此只需要配置FileField字段。
自定义的UploadFiles类的属性要和表单中提交的input的name属性相对应,不然在”is_valid()"验证时会失败!!
- 配置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 makemigrations
和python 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':'文件上传失败!'})
- 创建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%}
- 最后的项目结构
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掌握不熟练,因此暂时不去实践,希望我能快一点掌握好实现!