今天的Django教训汇总:前端上传excel文件到数据库(含下载)-20210415

本文核心在于# 1.自己动手:前端批量上传excel到数据库

1.自己动手:前端批量上传excel到数据库

思路:利用views.py来批量实例化model,然后循环读取openpyxl来获取表单数据,并保存在实例化后的model中。无需额外建立upload_models。
#models.py

class Employee(models.Model):
    eid = models.CharField(max_length=200,default='1',unique=True)
    name = models.CharField(max_length=200,null=True)
    dept_code = models.CharField(max_length=200,null=True)
    GENDER_CHOICES = (
        (u'Male', u'Male'),
        (u'Female', u'Female'),
    )
    gender = models.CharField(max_length=200,choices=GENDER_CHOICES,null=True)
    on_board = models.BooleanField(null=True)
    Range_CHOICES = (
        (u'R1', u'R1'),
        (u'R2', u'R2'),
        (u'R3', u'R3'),
        (u'R4', u'R4'),
    )
    Range = models.CharField(max_length=200,choices=Range_CHOICES,null=True)

    def __str__(self):
        return self.name

#forms.py

#Employee批量上传功能
class UploadEmployeeForm(forms.Form):
    uploadfile = forms.FileField()
    name = forms.CharField(max_length=50)

#views.py

# 批量上传employee
def upload_employee(request):
    if request.method == "POST":  #验证POST
        uf = UploadEmployeeForm(request.POST,request.FILES) #.post是获取post返回字段,.FILES是获取返回的文件
        print(uf)
        print(request.FILES['uploadfile'])
        print('-----------')
        if uf.is_valid(): #判断前台返回的表单是否为有效的类型
            wb = load_workbook(filename=request.FILES['uploadfile'])
            print(wb)
            ws = wb.get_sheet_names()
            ws = wb.get_sheet_by_name(ws[0])
            max_row = ws.max_row
            for row in range(2,max_row+1):
                #获取表单元素
                eid = ws.cell(row=row,column=1).value
                name = ws.cell(row=row,column=2).value
                dept_code = ws.cell(row=row,column=3).value
                gender = ws.cell(row=row,column=4).value
                on_board = ws.cell(row=row,column=5).value
                Range = ws.cell(row=row,column=6).value
                # 写入数据库
                my_upload_employee = Employee()
                my_upload_employee.eid = eid
                my_upload_employee.name = name
                my_upload_employee.dept_code = dept_code
                my_upload_employee.gender = gender
                my_upload_employee.on_board = on_board
                my_upload_employee.Range = Range
                my_upload_employee.save()
            return HttpResponse('upload ok!')
    else:
        uf = UploadEmployeeForm()
    return render(request,'myclass/upload_employee.html',{'uf':uf})

#urls.py

urlpatterns = [
''''''
    path('upload_employee/',views.upload_employee,name='upload_employee'),
''''''
]

#upload_employee.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>upload_employee</title>
</head>

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

</body>
</html>

#以下是成功的截图
在这里插入图片描述

在这里插入图片描述

2.他山之石:前端上传/下载文件到数据库

#models.py

from django.db import models


class newfile(models.Model):
    username = models.CharField(max_length = 30)
    headImg = models.FileField(upload_to= './upload/')
    headImg2 = models.FileField(upload_to='./upload/')
    #所以是用upload_to来指定文件存放的前缀路径

    def __str__(self):
        return self.username

#views.py

from django import forms
from django.http import HttpResponse, FileResponse
from django.shortcuts import render_to_response, render
from django.utils.http import urlquote

from onload.models import newfile

#建立Django表单,也可以在app下新建forms.py来引入
class UserForm(forms.Form):
    username = forms.CharField()    #字符串
    headImg = forms.FileField()     #文件类型
    headImg2 = forms.FileField()


def register(request):
    if request.method == "POST":  #验证POST
        uf = UserForm(request.POST,request.FILES) #.post是获取post返回字段,.FILES是获取返回的文件

        if uf.is_valid():               #判断前台返回的表单是否为有效的类型
            #获取表单元素
            username = uf.cleaned_data['username']
            headImg = uf.cleaned_data['headImg']
            headImg2 = uf.cleaned_data['headImg2']
            # 写入数据库
            user = newfile()

            user.username = username
            user.headImg = headImg
            user.headImg2 = headImg2

            user.save()
            return HttpResponse('upload ok!')
    else:
        uf = UserForm()
    return render_to_response('register.html',{'uf':uf})

#下载页面导航
def down(request):
    mail = newfile.objects.get(id=1)  #此处仅做第一条数据下载,如有需要,自行修改
    return render(request,'downland.html',{'i': mail})


#下载文件函数,根据down页面id自动返回id编号进行下载
def file_Download1(request,id):
    ts = newfile.objects.get(id=id).headImg
    tk = "F:/fileload/"+ str(ts)    #此处为upload地址+数据库存的路径,可根据实际情况修改
    file = open(tk, 'rb')
    response = FileResponse(file)
    response['Content-Type']='application/octet-stream'
    response['Content-Disposition']='attachment;filename="%s"' % (urlquote(tk))   #urlquote为中文转换,防止中文名文件下载名错误
    return response

def file_Download2(request,id):
    ts = newfile.objects.get(id=id).headImg2
    tk = "F:/fileload/"+ str(ts)    #此处为upload地址+数据库存的路径,可根据实际情况修改
    file = open(tk, 'rb')
    response = FileResponse(file)
    response['Content-Type']='application/octet-stream'
    response['Content-Disposition']='attachment;filename="%s"' % (urlquote(tk))   #urlquote为中文转换,防止中文名文件下载名错误
    return response

#urls.py

from django.contrib import admin
from django.urls import path,include
from myclass import views


urlpatterns = [
.....
    path('app/',views.register),
    path('down/',views.down),
    url(r'^np1/(\d+)/$', views.file_Download1, name='file_Download1'),
    url(r'^np2/(\d+)/$', views.file_Download2, name='file_Download2'),
......
]

#register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>register</h1>

    <form action="" method="post" enctype="multipart/form-data">

        {{uf.as_p}}
        <input type="submit" value="ok">
    </form>

</body>
</html>

在这里插入图片描述

#downland.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
                  username:{{ i.username }}<br>
                  附 件1:<a href="{% url 'file_Download1' i.id %}">{{ i.headImg }}</a><br>
                  附 件2:<a href="{% url 'file_Download2' i.id %}">{{ i.headImg2 }}</a><br>

</body>
</html>

在这里插入图片描述

3.自己动手:前端上传/下载文件到数据库

错误1:没有在urls中填写完路由。

  • 错误的urls.py
urlpatterns = [
    path('down/',views.down,name='down'),
]
  • 错误的提示
    在这里插入图片描述
  • 正确的urls.py
urlpatterns = [
    path('down/',views.down,name='down'),
    path('file_Download1/<int:id>/',views.file_Download1,name='file_Download1'),
    path('file_Download2/<int:id>/',views.file_Download2,name='file_Download2'),
]

错误2:带参数的url没有填对。

  • 错误的urls.py
urlpatterns = [
    path('file_Download1/(\d+)/',views.file_Download1,name='file_Download1'),
    path('file_Download2/(\d+)/',views.file_Download2,name='file_Download2')
]
  • 错误的提示
    在这里插入图片描述
  • 正确的urls.py
urlpatterns = [
    path('down/',views.down,name='down'),
    path('file_Download1/<int:id>/',views.file_Download1,name='file_Download1'),
    path('file_Download2/<int:id>/',views.file_Download2,name='file_Download2'),
]

错误3:点击附件下载,显示错误

解法请见连接
#错误前的显示
在这里插入图片描述

#错误的提示
在这里插入图片描述
#正确的改法
views.py添加from django.utils.http import urlquote

from django.utils.http import urlquote

#正确的显示下载
在这里插入图片描述

最终正确的代码

#views.py

# 登记用户上传的文件
def register2(request):
    if request.method == "POST":  #验证POST
        uf = UserForm2(request.POST,request.FILES) #.post是获取post返回字段,.FILES是获取返回的文件

        if uf.is_valid():               #判断前台返回的表单是否为有效的类型
            #获取表单元素
            username = uf.cleaned_data['username']
            headImg = uf.cleaned_data['headImg']
            headImg2 = uf.cleaned_data['headImg2']
            # 写入数据库
            user = newfile()

            user.username = username
            user.headImg = headImg
            user.headImg2 = headImg2

            user.save()
            return HttpResponse('upload ok!')
    else:
        uf = UserForm2()
    return render(request,'myclass/register2.html',{'uf':uf})


#下载页面导航
def down(request):
    mail = newfile.objects.get(id=1)  #此处仅做第一条数据下载,如有需要,自行修改
    return render(request,'myclass/downland.html',{'i': mail})


#下载文件函数,根据down页面id自动返回id编号进行下载
def file_Download1(request,id):
    ts = newfile.objects.get(id=id).headImg
    tk = os.path.join(BASE_DIR,str(ts))     #此处为upload地址+数据库存的路径,可根据实际情况修改
    file = open(tk, 'rb')
    response = FileResponse(file)
    response['Content-Type']='application/octet-stream'
    response['Content-Disposition']='attachment;filename="%s"' % (urlquote(tk))   #urlquote为中文转换,防止中文名文件下载名错误
    return response

def file_Download2(request,id):
    ts = newfile.objects.get(id=id).headImg2
    tk = os.path.join(BASE_DIR,str(ts))     #此处为upload地址+数据库存的路径,可根据实际情况修改
    file = open(tk, 'rb')
    response = FileResponse(file)
    response['Content-Type']='application/octet-stream'
    response['Content-Disposition']='attachment;filename="%s"' % (urlquote(tk))   #urlquote为中文转换,防止中文名文件下载名错误
    return response

#models.py

# 前端上传文件到数据库的试验
class newfile(models.Model):
    username = models.CharField(max_length = 30)
    headImg = models.FileField(upload_to= './upload/')
    headImg2 = models.FileField(upload_to='./upload/')
    #所以是用upload_to来指定文件存放的前缀路径

    def __str__(self):
        return self.username

#forms.py

#建立Django上传表单
class UserForm2(forms.Form):
    username = forms.CharField()    #字符串
    headImg = forms.FileField()     #文件类型
    headImg2 = forms.FileField()

#urls.py

urlpatterns = [
    path('register2/',views.register2,name='register2'),
    path('down/',views.down,name='down'),
    path('file_Download1/<int:id>/',views.file_Download1,name='file_Download1'),
    path('file_Download2/<int:id>/',views.file_Download2,name='file_Download2'),
]
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值