前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >django之文件上传下载等相关

django之文件上传下载等相关

作者头像
菲宇
发布2019-06-13 15:11:33
3K0
发布2019-06-13 15:11:33
举报
文章被收录于专栏:菲宇菲宇

一、文件上传

利用Django实现一个简单的文件上传功能。

实现步骤: 1)创建项目Django_upload:django-admin startproject Django_upload;创建app:cd Django_upload;python manage.py startapp blog。 2)设计模型(M) 这里的模型只包括了两个属性:用户名(即谁上传了该文件);文件名。具体形式如下所示: #coding=utf-8 from __future__ import unicode_literals from django.db import models class NormalUser(models.Model): username=models.CharField('用户名',max_length=30) #用户名 headImg=models.FileField('文件',upload_to='./upload')#文件名 def __str__(self): return self.username class Meta: ordering=['username']#排序风格username 同步数据库:Python manage.py makemigrations python manage.py migrate 3)设计视图(V) view.py: #coding=utf-8 from django.shortcuts import render,render_to_response from django import forms from django.http import HttpResponse from blog.models import * # Create your views here. class NormalUserForm(forms.Form): #form的定义和model类的定义很像 username=forms.CharField() headImg=forms.FileField() #在View中使用已定义的Form方法 def registerNormalUser(request): #刚显示时调用GET方法 if request.method=="POST": uf = NormalUserForm(request.POST,request.FILES)#刚显示时,实例化表单(是否有数据) if uf.is_valid():#验证数据是否合法,当合法时可以使用cleaned_data属性。 #用来得到经过'clean'格式化的数据,会所提交过来的数据转化成合适的Python的类型。 username = uf.cleaned_data['username'] headImg = uf.cleaned_data['headImg'] #write in database normalUser=NormalUser()#实例化NormalUser对象 normalUser.username = username normalUser.headImg = headImg normalUser.save()#保存到数据库表中 return HttpResponse('Upload Succeed!')#重定向显示内容(跳转后内容) else: uf=NormalUserForm()#刚显示时,实例化空表单 return render(request,'register.html',{'uf':uf})#只有刚显示时才起作用 配置urls.py: from django.conf.urls import url from django.contrib import admin from blog.views import * urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^register/$',registerNormalUser), ] 4)设计模板与表单(T)templates/register.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Register</title> </head> <body> <h2 align="center">Register</h2> <form method="POST" enctype="multipart/form-data"> {% csrf_token %} {{ uf.as_p }} <input type="submit" value="Submit"> </form> </body> </html> 在这里,表单方法为POST,enctype=”multipart/form-data”:表单数据被编码为一条消息。(一般用于传输二进制文件(图片、视频)) {% csrf_token %}: 跨域请求,我们需要在表单标签的内部加上这个模板标签,而且要在views.py中配合render不是render_to_response来实现。 {{ uf.as_p }}:这样一次性可以把表单里的所有字段给显示处理 显示结果: 上传 提交表单后: 提交表单 补充form显示单个元素: {{ field.label_tag }}: {{ field }} 比如我的form有个qq字段。那么就是这样写: {{ form.qq.label_tag }}#表示在form 里面定义这个字段的名称 {{ form.qq }}#根据这个字段在form定义的类型来决定。假设是char类型。那就是文本框 {{ form.qq.errors.as_text }}表示如果表单字段验证失败的话,这个代表错误信息 {{ form.qq.help_text }}如果你在form里定义了这个字段的帮助信息的话,就会在这里显示了 Django处理文件上传File Uploads HttpRequest.FILES 表单上传的文件对象存储在类字典对象request.FILES中,表单格式需为multipart/form-data <form enctype="multipart/form-data" method="post" action="/foo/"> <input type="file" name="image" /> request.FILES中的键来自于表单中的<input type="file" name="" />的name值: img=request.FILES['image'] request.FILES中的值均为UploadedFile类文件对象。 UploadedFile UploadedFile是类文件对象,具有以下方法和属性: UploadedFile.read() 读取整个上传文件的数据,文件较大时慎用。 UploadedFile.multiple_chunks(chunk_size=None) 判断文件是否足够大,一般为2.5M UploadedFile.chunks(chunk_size=None) 返回一个生成器对象,当multiple_chunks()为True时应该使用这个方法来代替read(). UploadedFile.name 上传文件的name。 UploadedFile.size 上传文件的大小。 UploadedFile.content_type 上传文件时的content_type报头,例如(e.g. text/plain or application/pdf). UpladedFile.charset 编码 存储文件 想将上传的文件存储在本地时: f=request.FILES['image'] with open('some/file/name.txt', 'wb+') as destination: for chunk in f.chunks(): destination.write(chunk) 使用Form处理上传文件 也可以使用django自带的form来处理上传文件。 先创建带FileFiled或者ImageFiled的Form: # In forms.py... from django import forms class UploadFileForm(forms.Form): title = forms.CharField(max_length=50) file = forms.FileField() 用Form处理: >>> f =UploadFileFormt(request.POST, request.FILES) view函数: from django.http import HttpResponseRedirect from django.shortcuts import render_to_response from .forms import UploadFileForm def handle_uploaded_file(f): with open('some/file/name.txt', 'wb+') as destination: for chunk in f.chunks(): destination.write(chunk) def upload_file(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): handle_uploaded_file(request.FILES['file']) return HttpResponseRedirect('/success/url/') else: form = UploadFileForm() return render_to_response('upload.html', {'form': form}) 使用Model处理上传文件 如果创建了一个带FileField或者ImageField域的Model,需要将上传文件存储到Model的FileFIeld域。 比如,使用nicEdit文本编辑器时,需要存储上传的文件,建立Model: from django.db import models class NicEditImage(models.Model): image = models.ImageField(upload_to='nicedit/%Y/%m/%d') 创建ModelForm: from django import forms class NicEditImageForm(forms.ModelForm): class Meta: model = NicEditImage view: def upload(request): if not request.user.is_authenticated(): json = simplejson.dumps({ 'success': False, 'errors': {'__all__': 'Authentication required'}}) return HttpResponse(json, mimetype='application/json') form = NicEditImageForm(request.POST or None, request.FILES or None) if form.is_valid(): image = form.save() #保存Form和Model json = simplejson.dumps({ 'success': True, 'upload': { 'links': { 'original': image.image.url}, 'image': { 'width': image.image.width, 'height': image.image.height} } }) else: json = simplejson.dumps({ 'success': False, 'errors': form.errors}) return HttpResponse(json, mimetype='application/json') 当然也可以手动存储文件到Model的文件域: from django.http import HttpResponseRedirect from django.shortcuts import render from .forms import UploadFileForm from .models import ModelWithFileField def upload_file(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): instance = ModelWithFileField(file_field=request.FILES['file']) #保存文件到FileField域 instance.save() return HttpResponseRedirect('/success/url/') else: form = UploadFileForm() return render(request, 'upload.html', {'form': form}) 不使用Form处理 想获得更大自由度时,可以全手动处理。 from django.db import models class Car(models.Model): name = models.CharField(max_length=255) price = models.DecimalField(max_digits=5, decimal_places=2) photo = models.ImageField(upload_to='cars') Model的FileField有以下属性: >>> car = Car.objects.get(name="57 Chevy") >>> car.photo <ImageFieldFile: chevy.jpg> >>> car.photo.name u'cars/chevy.jpg' >>> car.photo.path u'/media/cars/chevy.jpg' >>> car.photo.url u'http://media.example.com/cars/chevy.jpg' 可以手动修改文件的名称: >>> import os >>> from django.conf import settings >>> initial_path = car.photo.path >>> car.photo.name = 'cars/chevy_ii.jpg' >>> new_path = settings.MEDIA_ROOT + car.photo.name >>> # Move the file on the filesystem >>> os.rename(initial_path, new_path) >>> car.save() >>> car.photo.path '/media/cars/chevy_ii.jpg' >>> car.photo.path == new_path True Model的FileField是一个File对象,除了具有File对象的各种方法外,还有一个额外的save()方法: FieldFile.save(name, content, save=True)  name为存储名字,content为File或者File子类的实例 >>> car.photo.save('myphoto.jpg', content, save=False) >>> car.save() 类似于 >>> car.photo.save('myphoto.jpg', content, save=True) 手动存储: from django.core.files.base import ContentFile photo=request.FILES.get('photo','') if photo: file_content = ContentFile(photo.read()) #创建File对象 car.photo.save(photo.name, file_content) #保存文件到car的photo域 car.save() 一、简单文件上传实现 利用Django实现文件上传并且保存到指定路径下,其实并不困难,可以不需要用到django的forms,也不需要django的models,就可以简单实现上传功能。下面简单实现一下。 当Django在处理文件上传的时候,文件数据被保存在request.FILES。需要特别注意的是,只有当request方法是POST,且发送request的<form>有属性enctype=”multipart/form-data”时,表明不对字符进行编码,request.FILES中才会包含文件数据,否则request.FILES为空。 比如先写upload.html前面上传页面: # ./polls/templates/polls/upload.html<!DOCTYPE html><head> <meta charset="UTF-8"> <title>uploadFile</title></head><body> <form method="post" action="" enctype="multipart/form-data"> {% csrf_token %} <label> 上传文件 </label> <input type="file" name="myfile" /> <br/> <input type="submit" value="upload"/> </form></body></html> # ./polls/templates/polls/upload.html <!DOCTYPE html> <head> <meta charset="UTF-8"> <title>uploadFile</title> </head> <body> <form method="post" action="" enctype="multipart/form-data"> {% csrf_token %} <label> 上传文件 </label> <input type="file" name="myfile" /> <br/> <input type="submit" value="upload"/> </form> </body> </html> 然后写一个upload_file视图函数,处理文件上传,代码如下: # ./polls/viewsfrom django.shortcuts import renderfrom django.http import HttpResponsedef upload_file(request): # 请求方法为POST时,进行处理; if request.method == "POST": # 获取上传的文件,如果没有文件,则默认为None; File = request.FILES.get("myfile", None) if File is None: return HttpResponse("no files for upload!") else: # 打开特定的文件进行二进制的写操作; with open("/tmp/%s" % File.name, 'wb+') as f: # 分块写入文件; for chunk in File.chunks(): f.write(chunk) return HttpResponse("upload over!") else: return render(request, 'polls/upload.html') # ./polls/views from django.shortcuts import render from django.http import HttpResponse def upload_file(request): # 请求方法为POST时,进行处理; if request.method == "POST": # 获取上传的文件,如果没有文件,则默认为None; File = request.FILES.get("myfile", None) if File is None: return HttpResponse("no files for upload!") else: # 打开特定的文件进行二进制的写操作; with open("/tmp/%s" % File.name, 'wb+') as f: # 分块写入文件; for chunk in File.chunks(): f.write(chunk) return HttpResponse("upload over!") else: return render(request, 'polls/upload.html') 处理上传文件就是往服务器上生成一个文件,并将上传的文件内容写到新的文件中。然后写文件使用FILE.chunks()方法,而不是使用read()方法,能确保大文件并不会占用系统过多的内存。FILE方法和属性下面介绍。 最后写一个url匹配就可以了: # ./project_name/urls.pyurlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^polls/', include('polls.urls'))]# ./polls/urls.pyfrom django.conf.urls import urlfrom . import viewsapp_name = 'polls'urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^upload/$', views.upload_file, name='upload_file'),] # ./project_name/urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^polls/', include('polls.urls')) ] # ./polls/urls.py from django.conf.urls import url from . import views app_name = 'polls' urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^upload/$', views.upload_file, name='upload_file'), ] 最终效果如下图,选择文件就可以上传了: Django上传下载文件 那么这整个具体流程就是,访问http://10.10.0.109:8000/polls/upload/,调用upload_file函数,由于是GET请求,所以直接返回了upload.html页面,然后就可以进行POST请求上传文件了。 二、基于表单上传文件 在Django中我们可以采用Form类来处理表单,通过实例化处理和在模板中渲染,就可以轻松完成表单的需求,采用django的表单处理方式,能帮我们省去很多的工作,比如验证不能为空,或者要符合某种模式的输入才有效,这些处理起来非常方便,不用自己再单独写代码去验证表单的数据正确性,所以在开发中比较常用,Form提供了很多表单字段,比如日期,文本类型等,如果你熟悉基本的html,学起来会非常容易上手,下面只说下表单文件的上传,因为这个类型比较特殊,需要一点特殊的处理,我们来创建一个简单的一个实例: # ./polls/forms.pyfrom django import formsclass UploadFileForm(forms.Form): title = forms.CharField(max_length=50) file = forms.FileField() # ./polls/forms.py from django import forms class UploadFileForm(forms.Form): title = forms.CharField(max_length=50) file = forms.FileField() 这个表单就2个字段,要求用户title和上传一个文件或图片。 处理这个表单的视图会在request中接收到上传文件的数据。FILES是个字典,它包含每个FileField的键(或者ImageField,FileField的子类)。这样的话就可以用request.FILES[‘file’]来存放表单中的这些数据了。 注意request.FILES只有在请求方法为POST并且提交请求的<form>具有enctype=”multipart/form-data”属性时才包含数据。否则,request.FILES将为空。 大多数时候,你将只是简单地从request向表单中传递数据,就像Binding uploaded files to a form描述的那样。所以我们的视图处理逻辑基本类似下面这样: # polls/views.pyfrom django.shortcuts import renderfrom django.http import HttpResponsefrom polls.forms import UploadFileFormdef upload_file(request): if request.method == "POST": form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): handle_upload_file(request.FILES['file']) #handle_upload_file(form.files['file']) return HttpResponse('upload success!') else: form = UploadFileForm() return render(request, 'polls/upload.html', {'form': form}) # polls/views.py from django.shortcuts import render from django.http import HttpResponse from polls.forms import UploadFileForm def upload_file(request): if request.method == "POST": form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): handle_upload_file(request.FILES['file']) #handle_upload_file(form.files['file']) return HttpResponse('upload success!') else: form = UploadFileForm() return render(request, 'polls/upload.html', {'form': form}) 请注意,我们必须将request.FILES传递到form的构造函数中;这就是文件数据如何绑定到一个表单中。 这个函数判断用户的是否为POST请求,如果是并验证是有效的,然后就返回OK,在验证正确和返回OK的中间放我们的上传文件处理函数handle_upload_file,因为只有文件上传成功能返回OK。然后给这个handle_upload_file函数传递一个“request.FILES[‘file’]”,就是我们获取到的文件;也可以从表单中获取到,比如使用form提供的files或cleaned_data属性(form.files[‘file’]),这是表单提供的属性。如果是GET请求,就直接显示一个空表单,让用户输入。 注意我们必须向表单的构造器中传递request.FILES,这是文件数据绑定到表单的方法。FILES中的每个键为<input type=”file” name=”” />中的name。 然后写handle_upload_file函数,处理上传文件就是往服务器上生成一个文件,并将上传的文件内容写到新的文件中,所以它的基本函数是这样的,接收上传文件对象为参数,然后本地打开一个文件,从上传的文件中读出文件,写入新的文件中,代码如下: def handle_upload_file(file): with open("/tmp/%s" % file.name, 'wb+') as f: for chunk in file.chunks(): f.write(chunk) def handle_upload_file(file): with open("/tmp/%s" % file.name, 'wb+') as f: for chunk in file.chunks(): f.write(chunk) 接下来我们把form放到模板中去渲染,模板代码大概如下: # polls/templates/polls/upload.html<!DOCTYPE html><head> <meta charset="UTF-8"> <title>uploadFile</title></head><body> <form method="post" action="" enctype="multipart/form-data"> {% csrf_token %} {{ form }} <input type="submit" value="upload"/> </form></body></html> # polls/templates/polls/upload.html <!DOCTYPE html> <head> <meta charset="UTF-8"> <title>uploadFile</title> </head> <body> <form method="post" action="" enctype="multipart/form-data"> {% csrf_token %} {{ form }} <input type="submit" value="upload"/> </form> </body> </html> 这个表单被模板渲染后,看上去应该像下面这样,会生成静态源码: <label for="id_title">Title:</label><input type="text" name="title" id="id_title" required="" maxlength="50"><label for="id_file">File:</label><input type="file" name="file" id="id_file" required=""> <label for="id_title">Title:</label> <input type="text" name="title" id="id_title" required="" maxlength="50"> <label for="id_file">File:</label> <input type="file" name="file" id="id_file" required=""> 这样就完成了一个文件的上传,完毕。 上传数据在哪里储存? 在你保存上传文件之前,数据需要储存在某个地方。 通常,如果上传文件小于2.5MB,Django会把整个内容存到内存。这意味着,文件的保存仅仅涉及到从内存读取和写到磁盘,所以非常快。 但是,如果上传的文件很大,Django会把它写入一个临时文件,储存在你系统的临时目录中。在类Unix的平台下,你可以认为Django生成了一个文件,名称类似于/tmp/tmpzfp6I6.upload。如果上传的文件足够大,你可以观察到文件大小的增长,由于Django向磁盘写入数据。 这些特定值 – 2.5 MB,/tmp,以及其它 — 都仅仅是”合理的默认值”,它们可以自定义,这会在下一节中描述。 UploadedFile对象 在文件上传期间,实际文件数据存储在request.FILES中。此字典中的每个条目都是UploadedFile对象(或子类) – 上传文件的简单包装器。UploadedFile对象是对Python file对象的一个简单封装,并带有Django特定的附加功能。需要表示文件的时候,Django内部会使用这个类。UploadedFile对象拥有下列属性和方法: name 含有MEDIA_ROOT相对路径的文件名称。 size 文件的字节数。 mode 文件的读写模式。 open([mode=None]) 打开或者重新打开文件(同时会执行File.seek(0))。 mode参数的值和Python内建的open()相同。 重新打开一个文件时,无论文件原先以什么模式打开,mode都会覆盖;None的意思是以原先的模式重新打开。 read([num_bytes=None]) 读取文件内容。可选的size参数是要读的字节数;没有指定的话,文件会一直读到结尾。 __iter__() 迭代整个文件,并且每次生成一行。 File现在使用通用的换行符。以下字符会识别为换行符:Unix换行符’\n’,WIndows换行符’\r\n’,以及Macintosh旧式换行符\r。 chunks([chunk_size=None]) 迭代整个文件,并生成指定大小的一部分内容。chunk_size默认为64KB。 处理大文件时这会非常有用,因为这样可以把他们从磁盘中读取出来,而避免将整个文件存到内存中。 multiple_chunks([chunk_size=None]) 如果文件足够大,需要按照提供的chunk_size切分成几个部分来访问到所有内容,则返回True 。 write([content]) 将指定的内容字符串写到文件。取决于底层的储存系统,写入的内容在调用close()之前可能不会完全提交。 close() 关闭文件。 除了这些列出的方法,File沿用了file对象的以下属性和方法:encoding、fileno、flush、isatty、newlines、read、readinto、readlines、seek、softspace、tell、truncate、writelines、xreadlines。 基于这些属性和方法,我们把代码很轻松写的更规范,比如限制上传文件大小等。 三、文件下载 基于Django建立的网站,如果提供文件下载功能,最简单的方式莫过于将静态文件交给Nginx等处理,但有些时候,由于网站本身逻辑,需要通过Django提供下载功能,如页面数据导出功能(下载动态生成的文件)、先检查用户权限再下载文件等。因此,有必要研究一下文件下载功能在Django中的实现。 最简单的文件下载功能的实现 将文件流放入HttpResponse对象即可,如: def download_file(request): # do something... with open('/tmp/file_name.txt', 'rb') as f: c = f.read() return HttpResponse(c) def download_file(request): # do something... with open('/tmp/file_name.txt', 'rb') as f: c = f.read() return HttpResponse(c) 这种方式简单粗暴,适合小文件的下载,但如果这个文件非常大,这种方式会占用大量的内存,甚至导致服务器崩溃。 更合理的文件下载功能 Django的HttpResponse对象允许将迭代器作为传入参数,将上面代码中的传入参数c换成一个迭代器,便可以将上述下载功能优化为对大小文件均适合;而Django更进一步,推荐使用 StreamingHttpResponse对象取代HttpResponse对象,StreamingHttpResponse对象用于将文件流发送给浏览器,与HttpResponse对象非常相似,对于文件下载功能,使用StreamingHttpResponse对象更合理。 因此,更加合理的文件下载功能,应该先写一个迭代器,用于处理文件,然后将这个迭代器作为参数传递给StreaminghttpResponse对象,如: from django.http import StreamingHttpResponsedef download_file(request): def file_iterator(file, chunk_size=512): with open(file) as f: while True: c = f.read(chunk_size) if c: yield c else: break file = "file_name.txt" response = StreamingHttpResponse(file_iterator(file)) return response from django.http import StreamingHttpResponse def download_file(request): def file_iterator(file, chunk_size=512): with open(file) as f: while True: c = f.read(chunk_size) if c: yield c else: break file = "file_name.txt" response = StreamingHttpResponse(file_iterator(file)) return response 文件下载功能再次优化 上述的代码,已经完成了将服务器上的文件,通过文件流传输到浏览器,但文件流通常会以乱码形式显示到浏览器中,而非下载到硬盘上,因此,还要在做点优化,让文件流写入硬盘。优化很简单,给StreamingHttpResponse对象的Content-Type和Content-Disposition字段赋下面的值即可,如: response['Content-Type'] = 'application/octet-stream'response['Content-Disposition'] = 'attachment;filename="test.pdf"' response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename="test.pdf"' 所以,完整代码如下: from django.http import StreamingHttpResponsedef download_file(request): def file_iterator(file, chunk_size=512): with open(file) as f: while True: c = f.read(chunk_size) if c: yield c else: break file = "big_file.pdf" response = StreamingHttpResponse(file_iterator(file)) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename="{0}"'.format(file) return response from django.http import StreamingHttpResponse def download_file(request): def file_iterator(file, chunk_size=512): with open(file) as f: while True: c = f.read(chunk_size) if c: yield c else: break file = "big_file.pdf" response = StreamingHttpResponse(file_iterator(file)) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename="{0}"'.format(file) return response Django 图片上传到数据库 并调用显示 环境:Django2.0 Python3.6.4 建立项目,数据库设置,就不说了。 直接上代码: 在models.py中,需要建立模型,这里使用了ImageField字段,用来存储图片路径,这个字段继承了FileField字段,本质上是一样的。这里Image.Field的默认max_length=100,我们可以根据需求自己指定。upload_to用于指定上传到哪个路径下。 PS: 使用ImageField首先需要装Pillow。 1 pip install Pillow 1 class Test(models.Model): 2 name = models.CharField(max_length=50) 3 image = models.ImageField(upload_to='logo') 4 def __str__(self): 5 return self.name 建立好模型,需要进行迁移操作, 1 python manage.py makemigrations 2 python manage.py migrate 在settings.py中,设置MEDIA_URL和MEDIA_ROOT MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 我们需要告诉Django,媒体文件的位置在哪里。这样就和数据库存储的路径相对应了,具体就是MEDIA_ROOT指定目录,upload_to就是在这个目录下进行操作。 1. 显示图片(图片调用)   为了能够方便录入数据,我们使用django后台管理,创建管理页面。 1 python manage.py createsuperuser   根据提示进行创建。在app下admin.py中将需要上面创建的模型进行添加。 1 admin.site.register(Test)    开启runserver,打开admin页面,就可以创建具体的数据了,将图片进行添加。   我们需要调用的话,需要在view.py中将数据进行传递。 img = Test.objects.all() return render(request, 'home.html', {'img':img})    在视图函数中加入,上面两句。在模板中,将图片展现出来: {% for i in img %} <img src="{{ MEDIA_URL }}{{ i.image }}"> {% endfor %}   这里{{ MEDIA_URL }}是必须要的,因为数据库取出来的地址是/logo/img001.png这种,路径不完整,我们存储的路径上/media/logo/img001.png    但到这里还是不能正常显示图片,会显示404,是因为图片的url也是需要通过django进行指派,我们还需要在urls.py进行设定。   为了html模板能正确找到MEDIA_URL,TEMPLATES中导入相关的包。 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'django.template.context_processors.media',#### add here ], }, }, ]     直接参考官方文档即可。这样图片的url才是完整的,我们的页面才可以正常显示图片。 2. 上传图片   我们可能需要用户上传自己的头像,或者相册,这里做一个简单的示范:   首先需要一个form,enctype="multipart/form-data" method="post" 是必须要填写的,表示数据不经过编码,直接上传。{%csrf_token%}也是post时,django强制要求的。 <form enctype="multipart/form-data" action="#" method="post"> {% csrf_token %} <input type="text" name="name"> <input type="file" name="logo"> <input type="submit" value="upload"> </form>   然后需要去views.py对视图函数进行操作。 if request.method == 'POST': file = request.FILES['logo'] if file: new_img = Test( name=request.POST.get('name'), image=file ) new_img.save()   与普通的数据不同,这里使用了request.FILES字典的方式去获取文件,然后创建新的数据,并保存到数据库中。

http://www.ywnds.com/?cat=38

https://yiyibooks.cn/xx/django_182/ref/forms/api.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年05月26日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档