5-11 上传Excel和Form上传

  案例1:批量上传数据

在部门管理的页面上再提供一个批量导入的功能,页面上提供一个上传Excel的面板,用户上传Excel后提交到数据库,数据库增加数据后返回到页面当中。

 

 

 

 在组件-Bootstrap v3 中文版中找样式:

 

 

 

  在全局css样式中找表单:

 

 

 最后选用的表单样式为:

 效果为:

      

最后不影响其他功能,上传文件到新的目标地址:

备注:文件的上传方式method一定得是post,action指的是目标地址。

 在url中进行添加

 path('depart/multi/', depart.depart_multi),

在depart_list.html中的input框添加name:

 

 

 

在部门列表depart.py中:


def depart_multi(request):
    """"批量上传(Excel文件)"""
    file_object = request.FILES.get("exc")
    print(type(file_object))
    return HttpResponse('上传文件')  #上传成功的话会在depart/muliti显示”上传文件“的文字
注意:会得到403 forbidden的错误:

  在depart_list.html中加入

 

 

 上传成功后会得到一个对象:

 

 

 查看对象的功能添加如下操作:

 

 

 

 点进去得到一个类,如下图所示:

 

 

 

 

要想直接读取Excel,首先要安装openpyxl,故执行命令:  

pip3.9 install openpyxl

 

 

 

 直接打开Excel文件并读取内容的操作:

def depart_multi(request):
    """"批量上传(Excel文件)"""

    # #直接打开Excel并读取内容(以前的操作)
    # from openpyxl import load_workbook
    # wb = load_workbook("文件路径")
    # sheet = wb.worksheets[0]

    from openpyxl import load_workbook
    #现在的操作如下:
    #1.获取用户上传的文件对象
    file_object = request.FILES.get("exc")
    print(type(file_object))
    # 2.对象传递给openpyxl,由openpyxl读取文件的内容
    wb = load_workbook(file_object)
    sheet = wb.worksheets[0]

    cell = sheet.cell(1, 1)
    print(cell.value)

    return HttpResponse('上传文件')

读取的文件数据:(第一行第一列数据为ID):

 

 

cell = sheet.cell(1, 2)

读取的文件数据:(第一行第二列数据为姓名):

 

 

 

代码:

效果如下:

 

  代码:

 

         :

 

 效果如下:

 

 整个Excel文件导入数据库的代码如下:

#from django.http import HttpResponse
from django.shortcuts import redirect

from app01 import models


def depart_multi(request):
    """"批量上传(Excel文件)"""

    # #直接打开Excel并读取内容(以前的操作)
    # from openpyxl import load_workbook
    # wb = load_workbook("文件路径")
    # sheet = wb.worksheets[0]

    from openpyxl import load_workbook
    ##上传文件并添加到数据库中,现在的操作如下:
    # 1.获取用户上传的文件对象
    file_object = request.FILES.get("exc")
    # print(type(file_object))
    # 2.对象传递给openpyxl,由openpyxl读取文件的内容
    wb = load_workbook(file_object)
    sheet = wb.worksheets[0]

    # cell = sheet.cell(1, 1)   获取某一个sheet
    # print(cell.value)
    # 将Excel文件的数据进行循环并写入数据库
    # 3.
    for row in sheet.iter_rows(min_row=2):  # 从第二行往下取,如果想要直接从第一行取,只要sheet.rows即可
        # print(row) #循环获取每一行数据
        # 3.1 要取到每行第一列的数值
        text = row[0].value
        # print(text)
        exists = models.Departmemt.objects.filter(title=text).exists()
        if not exists:
            models.Departmemt.objects.create(title=text)  # 数据添加到数据库

    # return HttpResponse('上传文件')
    return redirect('/depart/list/')#添加到数据库成功后,回到部门列表里

上传一个文件,只用写一个标签,

 案例2:混合数据【Form](包含封面、图像、图标的数据)

提交页面:用户输入数据+文件(输入不能为空、报错)。

  • Form生成HTML标签:type=file(原来是只能input ,type=text)
  • 表单的验证
  • form.cleaned_data 获取数据+文件对象 
  • 基于form自己拿到对象,往数据库中存储。

首先,另外做一个Form 上传的菜单,操作如下:

 

 在url.py中添加

 在upload.py中代码如下:

  在upload_form.html中采用前面的change,html的模版另外加以下:

 

from django import fo

class UpForm(forms.Form):
    name = forms.CharField(label="姓名")
    age = forms.IntegerField(label="年龄")
    img = forms.FileField(label="头像")


def upload_form(request):
        title = "Form上传"
    if request.method == "GET":
        form = UpForm
        return render(request, 'upload_form.html', {"form": form, "title": title})#把参数form和title渲染到HTML里

    form = UpForm(data=request.POST, files=request.FILES)  #进行表单验证,一个是接收表单数据,一个是接收文件数据
    if form.is_valid():
        #{'name':'武沛齐','age':123,'img':<InMemoryUploadedFile:图片1.png (image/png)>}

print(form.cleaned_data) return HttpResponse("...") return render(request, 'upload_form.html', {"form": form, "title": title})

 

 

 

 

 

 

 #读取到内容,自己处理每个字段的数据,让它进行存储,即导入到数据库。

#1.读取图片内容,写入到文件夹中并获取文件的路径。 #2.将图片文件路径写入到数据库

 

 

此时已经可以得到想要的样子,完善功能加上Bootstrap将每一个字段循环加上样式:

 

 

 

 

将部分字段设置成不加入样式操作如下:

 

 

 

 

在upload.py中输入一行代码即可完成所要功能。

  

现在后台以POST的方式接收数据。以GET的形式使用户直接看到页面form,以POST方式提交过来的需要进行表单验证。

最终代码:

import os

from django.contrib.sites import requests
from django.shortcuts import render, HttpResponse

from app01 import models

from django import forms
from app01.utils.bootstrap import BootstrapForm


class UpForm(BootstrapForm):
    bootstrap_exclude_fields = ['img']

    name = forms.CharField(label="姓名")
    age = forms.IntegerField(label="年龄")
    img = forms.FileField(label="头像")


def upload_form(request):
    title = "Form上传"
    if request.method == "GET":
        form = UpForm
        return render(request, 'upload_form.html', {"form": form, "title": title})  # 把参数form和title渲染到HTML里

    form = UpForm(data=request.POST, files=request.FILES)

    if form.is_valid():
        # {'name':'武沛齐','age':123,'img':<InMemoryUploadedFile:图片1.png (image/png)>}  获取到的数据
        print(form.cleaned_data)
        # 读取到内容,自己处理每个字段的数据,让它进行存储,即导入到数据库.
        # 1.读取图片内容,写入到文件夹中并获取文件的路径。

        image_object = form.cleaned_data.get("img")
        # file_path = "app01/static/img/{}".format(image_object.name)  # 进行原文件的路径填写
        file_path = os.path.join("app01", "static", "img", image_object.name)  # 存储到路径
        f = open(file_path, mode='wb')
        for chunk in image_object.chunk():
            f.write(chunk)
        f.close()  # 循环读取文件往本地新文件中写

        # 2.将图片文件路径写入到数据库(拼接路径)
        models.Boss.objects.create(
            name=form.cleaned_data['name'],
            age=form.cleaned_data['age'],
            img=file_path,
        )
        # 前面两个原封不动,数据都在cleaned_data中,最后一个文件用路径写入到数据库
        return HttpResponse("...")
    return render(request, 'upload_form.html', {"form": form, "title": title})

最终效果:

 

 

 

 

 

 

 

 

 

 用户要看到图片直接在网页地址中输入用域名+数据库的路径,即

db_file_path
效果如图:

 

 

 最终代码:

import os

from django.contrib.sites import requests
from django.shortcuts import render, HttpResponse

from app01 import models

from django import forms
from app01.utils.bootstrap import BootstrapForm


class UpForm(BootstrapForm):
    bootstrap_exclude_fields = ['img']

    name = forms.CharField(label="姓名")
    age = forms.IntegerField(label="年龄")
    img = forms.FileField(label="头像")


def upload_form(request):
    title = "Form上传"
    if request.method == "GET":
        form = UpForm
        return render(request, 'upload_form.html', {"form": form, "title": title})  # 把参数form和title渲染到HTML里

    form = UpForm(data=request.POST, files=request.FILES)

    if form.is_valid():
        # {'name':'武沛齐','age':123,'img':<InMemoryUploadedFile:图片1.png (image/png)>}  获取到的数据
        print(form.cleaned_data)
        # 读取到内容,自己处理每个字段的数据,让它进行存储,即导入到数据库.
        # 1.读取图片内容,写入到文件夹中并获取文件的路径。

        image_object = form.cleaned_data.get("img")
        # file_path = "app01/static/img/{}".format(image_object.name)  # 进行原文件的路径填写
        db_file_path = os.path.join("static", "img",
                                    image_object.name)  # 数据库中的file_path 存成 "static", "img", image_object.name
        file_path = os.path.join("app01", db_file_path)  # 文件中存储路径成"app01", "static", "img", image_object.name
        f = open(file_path, mode='wb')
        for chunk in image_object.chunk():
            f.write(chunk)
        f.close()  # 循环读取文件往本地新文件中写

        # 2.将图片文件路径写入到数据库(拼接路径)
        models.Boss.objects.create(
            name=form.cleaned_data['name'],
            age=form.cleaned_data['age'],
            img=db_file_path,
        )
        # 前面两个原封不动,数据都在cleaned_data中,最后一个文件用路径写入到数据库
        return HttpResponse("...")
    return render(request, 'upload_form.html', {"form": form, "title": title})

注意:就目前而言,所有的静态文件都只能放在static目录。

 

 

 

 

 

 

  

    

 

posted @ 2022-05-06 16:26  费皿啊  阅读(235)  评论(0)    收藏  举报