django 搭建上传文件系统——细说Form Validation(二)
我学习django的主要途径是http://djangobook.com, 作者的书好像也出版了。作者的思路很清爽,讲解浅显易懂,该深入的地方深入,我很喜欢,比django官方文档感觉好多了,官方文档讲解的太晦涩。这些随笔是结合一些例子来细说django的学习要点与本人的学习心得。
有些中文博客也讲解了用django做一些小的项目,但是没有细讲django的原理,即为什么要这样做,我就个人的理解会细致地讲解各个部分的知识点。希望能帮助更多人,也希望与更多人一起进步。
本人配置环境:(2017.6.20)
注意: 在windows中的文件系统是用反斜杠'\'来表示,但是即使是在windows系统下的django,在表示文件路径时依然用unix 风格的斜杠'/'
OS: win7
python:3.6.2
Django: 1.11.2
创建项目与应用
每个项目的前部分:创建项目与应用,把应用添加到settings.py 的'INSTALLED_APP'里,在settings.py里设置默认的数据库,并同步数据库数据的操作都是一样的,就不具体叙述,可以参考我前面的例子。
我把这个上传文件的项目命名为disk, 项目名称为mysite,创建完成后的结构如下:(disk/templates, disk/uploads, disk/forms.py 是我本人创建的,不是系统创建的。请忽略除mysite, disk以外的部分,与此例无关。)
# Application definition INSTALLED_APPS = ('django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','disk', )
创建Form类实例
为了简单起见,在这个文件上传系统中,我们只设计两个变量:上传文件的用户改名,及上传的文件。Django中为用户定义了一个django.forms库,这个库可以方便地进行form类的数据显示及数据验证,省去了很多用户的代码。django.forms库用起来也方便,只需要在HTML文件中需要增加<form> tag时,定义相应的 Form 类就可以。在以下的示例中我们最终的页面上只有一个<form> tag, 所以我们只需要定义一个Form类即可。Django 社区的惯例是把Form类单独放在一个forms.py文件中,我们最好也遵循这个规则。创建disk\forms.py文件,并写入:
# mysite\disk\forms.pyfrom django import formsclass UserForm(forms.Form):userName = forms.CharField(max_length = 20)uploadFile = forms.FileField()
可以看出Form类的语法与定义Model时的语法很像,对于每个变量都要定义它的域的属性,这个我在下面的Model章节中会仔细再讲。在UserForm中,我们定义了userName,它是字符属性,还定义了uploadFile,它是文件属性。默认情况下这两个变量都是不能为空的,如果为空,则会在html页面中显示出相应的错误。
创建Models(数据库层)
我们需要把用户名和上传的文件路径放到数据库中, 所以在设计数据库时需要两个字段:userName and uploadFile。在disk\models.py文件中写入:
# disk\models.pyfrom django.db import models# Create your models here. class User(models.Model):userName = models.CharField(max_length = 30)uploadFile = models.FileField(upload_to = 'disk/upload/')def __str__(self):return self.userName
对于models的定义,要讲的东西很多。
- 每个变量都要定义成某种类型的域(field),django会根据不同的域来决定某些事情。比如,域的类型会决定数据库中该变量的数据类型(比如INTERGER, VARCHAR)。对于每个变量,在html显示层,django把它定义成一个单独的widget。最终是以什么widget显示变量也是与该域的类型有关的,比如一个CharField变量最终会以<input type= 'text'>的形式显现。
- 以下是每种域类型变量的定义,来自http://www.djangobook.com/model-definition-reference/。为了保证释义的完整性与准确性,我就不翻译成中文了:
下张表是所有域通用的可选参数:
- FileFiled 说明:此类变量不支持primary_key, unique参数(见上表)。有两个可选参数:upload_to和storage。'upload_to'定义的是一个本地的文件路径,这个路径可以是个相对路径,它会自动加到settings.py文件中 BASE_DIR 目录的后面。一般情况下,即使文件上传成功也不会保存到数据库中,除非显性的调用save()函数。从性能上考虑,不会把上传的文件存储到数据库中,而是把文件的路径存储到数据库中(如果调用了save()函数)。
- 在定义完models后,要把它同步到数据库中,主要用两个命令python manage.py makemigrations, python manage.py migrate
创建Views (逻辑层)
视图views决定的是按照怎样的逻辑收集处理数据,并把用户的数据呈现给用户;可以把它理解成用户数据(数据库)到最终呈现页面(web页面)的中间人。这部分一般就是纯粹的python代码。打开mysite\disk\views.py文件并写入:
# mysite\disk\views.pyfrom django.shortcuts import render from disk.forms import UserForm from disk.models import Userdef uploads(request):if request.method == 'POST':userform = UserForm(request.POST, request.FILES)if userform.isValid():user = User()user.userName = userform.cleaned_data['userName']user.uploadFile = userform.cleaned_data['uploadFile']user.save()return render(request, 'uploadOK.html')else:userform = UserForm(initial ={'userName': 'sunshore'})return render(request, 'upload.html', {'userform': userform})
views.py文件就把上文定义的UserForm和User (models文件)引用了过来。
- 对于HttpRequest.POST对象,我们在上一节中讲过,这里不再叙述。
- HttpRequest.FILES对象也是一个“类字典”对象,它的'key'是文件名,与html文件中<input type = "file" name = "" />中的内容相同;'key'所对应的'value' 是上传的文件。注意: 这个对象必须是在HttpRequest method = 'POST' 并且<form> tag中包含 enctype="multipart/form-data"时才会有值,否则会返回一个空的类字典对象。
- django中Form类实例化后,可以通过isValid()函数来检查数据是否有效;如果有效,则该实例就会有cleaned_data属性,这是一个字典对象,包含的是Form类数据。
- 我们首先检查HttpRequest是一个POST 方法,然后实例化Form类,如果实例化成功,就把数据存储到数据库中去。(当然最终存储到数据库中不是文件本身,而是文件路径,上部分提到过)。如果HttpRequest不是POST方法,则把用户名初始化成'sunshore'。
创建Templates(显示层)
我们需要创建templates来定制数据的显示。Django中将数据的处理与显示分开了,数据的处理是在views.py中,数据的显示是在templates里。 默认情况下,mysite/mysite/settings.py文件中的TEMPLATES定义'APP_DIRS' = True, 也就是说django会到各个应用的文件下寻找templates文件夹,使用里面定义的html文件。
我们需要在mysite/disk/templates创建两个html文件:upload.html和uploadOK.html,并写入:
# mysite\disk\templates\upload.html<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <style type="text/css">
ul.errorlist{
margin:0;
padding:0;
}
.errorlist li{
background-color: blue;
color: white;
display: block;
font-size: 1.0em;
margin: 0 0 1px;
padding: 0 10px;
}
</style>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Upload File</title> </head> <body><h1>User Upload Files</h1><form action="" method="post" enctype="multipart/form-data" >{{userform.as_p}}{% csrf_token %} <input type="submit" value="ok"/></form> </body> </html>
# mysite\disk\templates\uploadOK.html<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Upload OK</title> </head> <body><p > Uploading Files Successfully </p><a href= 'upload'>Back to upload file page </a></body> </html>
- Form类会自动生成页面的错误信息,并以errorlist的形式返回结果。在html文件中我们可以对errorlist进行CSS的定制,使得error信息更为突出。这就是<style> ....</style>那段代码的作用。
- 默认情况下,Form类显示成员的排版格式有form.as_p, form.as_table, form.as_ul这三种形式,不同形式下成员的排列是不同的。比如本示例中userform.as_p会显示如下:
userform.as_table 显示结果:
userform.as_ul 显示结果:
我们可以根据自己的喜好来选择成员的显示形式。当然django也支持自己定制所有成员的显示形式。感兴趣的读者可以参考:http://djangobook.com/tying-forms-views.
设置urlconf 文件
这个是用正则表达式的方式定义了HttpRequest.url和views的对应关系。在mysite\urls.py文件中输入:
# mysite\urls.pyfrom django.conf.urls import patterns, include, urlfrom django.contrib import admin admin.autodiscover()from disk import views as disk_viewsurlpatterns = patterns('',# Examples:# url(r'^$', 'mysite2.views.home', name='home'),# url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)),url(r'^upload/$', disk_views.upload), )
启动服务
在mysite文件夹下,终端命令行输入: python manage.py runserver 80
在用户正确地上传了文件后,我们可以在mysite\disk\upload文件夹下看到此文件,这个是在models.py里定义的,读者们可以试一下。
转载于:https://www.cnblogs.com/sunshore/p/7054738.html
django 搭建上传文件系统——细说Form Validation(二)相关推荐
- Django上传文件,制作文件上传按钮,form上传文件
Django上传文件,制作文件上传按钮,form上传文件 from django.shortcuts import renderfrom django.shortcuts import HttpRes ...
- Django文件上传***
分别用三种Django文件上传方式(form方式.jQuery+jQuery.ajax方式.原生JS+原生ajax方式)做上传功能示例 文件 文件释义 form_upload.html form上传文 ...
- Django Admin 上传多张图片并显示缩略图
Django Admin 上传多张图片并显示缩略图 文章目录 Django Admin 上传多张图片并显示缩略图 1.效果预览 2.自定义Widget 3.定义模型和模型表单 3.1 定义模型 3.2 ...
- django + python上传文件的两种方式
突然心血来潮,研究了下django+python上传文件的两种方式. 第一:直接采用文件读写的方式上传 1. settings.py文件中设置文件的存放路径和文件读取路径 MEDIA_ROOT = o ...
- django文件上传到服务器,django上传文件的三种方式
Django文件上传需要考虑的重要事项 文件或图片一般通过表单进行.用户在前端点击文件上传,然后以POST方式将数据和文件提交到服务器.服务器在接收到POST请求后需要将其存储在服务器上的某个地方.D ...
- 渗透测试-文件上传之过滤绕过(二)
文件上传之过滤绕过(二) 文件上传实验室第3,4关 文章目录 文件上传之过滤绕过(二) 前言 一.下载upload实验室,进行练习 二.进行后缀名绕过,拿shell 1.更改后缀名.php3绕过 2. ...
- django文件上传
Django在处理文件上传时,文件数据被打包封装在request.FILES中. 一.简单上传 首先,写一个form模型,它必须包含一个FileField: # forms.py from djang ...
- Django 图片上传upload_to路径指定失效的问题记录
为什么80%的码农都做不了架构师?>>> 初始方法一: 疑虑:model使用upload_to自定义路径方法失效,指定路径也失效.最后以Views中指定MEDIA_URL和ME ...
- django实现上传文件并保存
这一部分包括以下几个部分:media配置,前端html上传,数据库保存模块Model,表单验证Form,url配置,后端处理逻辑View 文章目录 media配置 HTML设计 Model编写 For ...
- html上传图片至数据库,Django 图片上传到数据库 并调用显示
环境:Django2.0 Python3.6.4 建立项目,数据库设置,就不说了. 直接上代码: 在models.py中,需要建立模型,这里使用了ImageField字段,用来存储图片路径,这个字段继 ...
最新文章
- BZOJ 2957楼房重建
- 简单选择排序 c代码
- maven打包时加入依赖包及加入本地依赖包
- micropython oled中文_micropython esp8266+ssd1306(OLED) 显示中文(示例)
- 阿里云视频云 Retina 多媒体 AI 体验馆开张啦!
- IntelliJ IDEA 快捷键(一)(window版)
- Linux给Java程序设置端口_扫描服务端口的Java程序
- liunx 下的动态地址分配服务DHCP
- 网易市值超百度 成为国内第五大互联网公司
- 字节流转字符流OutputStreamWriter、InputStreamReader,关闭流的方法
- 华为路由器防火墙配置命令总结(上)
- 关于Redis启动时报权限不够(-bash: /usr/local/bin/redis-server: Permission denied)
- 百度地图API地理位置和坐标转换 城市坐标
- MATLAB基础绘图操作
- 企业微信的好处和功能介绍 | 最新企业微信电脑版下载
- 帆软报表设置的参数不显示_FineReport报表工具显示格式和显示值的设置
- 高德地图点击不同的标记,动态传入参数创建信息窗体
- 建设内链要注意的事项
- 福特汉姆大学计算机科学专业,福特汉姆大学计算机科学专业
- 2021BI及数据可视化领域最具商业合作价值企业盘点