django上传、下载文件

直接上干货吧:

1、文件上传:

  a. models.py

    

from django.db import models
from . import storage

class UploadFile(models.Model):
    title = models.CharField(max_length=50)
    file = models.FileField(upload_to='./filesupload',storage=storage.FieldStorage())

    def __unicode__(self):
        return self.title

    class Meta:
        ordering = ['title']

    创建一个UploadFile模型,参数upload_to表示文件上传的位置,

    在此之前还需要在settings文件中设置MEDIA_ROOT、MEDIA_URL:

 FILE_UPLOAD_HANDLERS = [
    "django.core.files.uploadhandler.MemoryFileUploadHandler",
    "django.core.files.uploadhandler.TemporaryFileUploadHandler"
  ]

MEDIA_ROOT = os.path.join(BASE_DIR,'files')
MEDIA_URL = '/files/'

    同步数据库

  b. 新建forms.py文件:

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file = forms.FileField()

  c. 在views.py中写上传文件方法:

def upload_file(request):
    context = {}
    if request.method == 'POST':
        form = UploadFileForm(request.POST,request.FILES)
        if form.is_valid():
            title = form.cleaned_data['title']
            file = form.cleaned_data['file']

            uploadfile = UploadFile()
            uploadfile.title = title
            uploadfile.file = file
            uploadfile.save()

            return HttpResponse('success')
    else:
        form = UploadFileForm()
    context['form'] = form
    return render(request,'upload.html',context)

  d. 创建模板 upload.html:

<h2 align="center">上传</h2>

    <form method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="Submit">
     </form>

  e. urls.py

path('',views.upload_file,name="upload" ),

  f. 效果:

2、文件下载:

  我在这里分为两部分,一部分是文件列表、另一部分是文件下载

    a. views.py  

def download_file(request):
    files = UploadFile.objects.all()
    context = {}
    context['files'] = files

    return render(request,'download.html',context)

def download(request,file_pk):
    file = UploadFile.objects.filter(pk=file_pk)[0]
    filename = file.file
    name = str(filename).split('/')[-1]
    filelocal = 'Files/'+str(filename)

    file = open(filelocal) 

    def file_iterator(file_name, chunk_size=512):
        with open(file_name,'rb') as f:
            while True:
                c = f.read(chunk_size)
                if c:
                    yield c
                else:
                    break
        
    response = StreamingHttpResponse(file_iterator(filelocal))
    response['Content-Type']='application/octet-stream'
    response['Content-Disposition']='attachment;filename="'+str(name)+'"'
    return response

    download_file是要下载的文件列表,download是文件下载的链接。因为文件下载非常不熟悉,所以代码写的很烂,通过file_pk将文件从数据库中筛选出来,filelocal是文件的储存路径

    b. 新建urls.py文件:

path('downloadlist',views.download_file,name="download_list"),
path(r'download/<int:file_pk>',views.download,name="download"),

  c. download.html:

<ul>
    {% for file in files %}
        <li>{{ file.title }}<a href="{% url 'download' file.pk %}" rel="external nofollow" >点我下载</a></li>
    {% endfor %}
</ul>

  d. 创建 storage.py:

    这是为了将上传的文件重命名,因为在我编写的过程中发现,当我的文件名称中含有中文时,下载下来的文件会出错误(我也不清楚这是为什么......),于是从其他大神的博客中找到了将文件重命名的方法,这样下载下来的文件就可以正常打开了。

from django.core.files.storage import FileSystemStorage
import os,time,random

class FieldStorage(FileSystemStorage):
    from django.conf import settings

    def __init__(self, location=settings.MEDIA_ROOT, base_url=settings.MEDIA_URL):
        super(FieldStorage, self).__init__(location, base_url)

    def _save(self, name, content):
        ext = os.path.splitext(name)[1]
        d = os.path.dirname(name)
        fn = time.strftime('%Y%m%d%H%M%S')
        fn = fn + '_%d' % random.randint(10000, 99999)
        name = os.path.join(d, fn + ext)
        return super(FieldStorage, self)._save(name, content)

  e. 效果:

猜你喜欢

转载自www.cnblogs.com/chrran/p/11444359.html