文件上传

1. 基本操作

1
2
3
4
5
6
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="username">
<input type="file" name="avatar">
<input type="submit" value="提交">
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
def upload_list(request):
if request.method == 'GET':
return render(request,"upload_list.html")
# 获取文件对象
file_obj = request.FILES.get('avatar')

# 将上传的文件本地保存
f = open(file_obj.name,mode='wb')
# 上传的文件按一块一块的读取
for chunk in file_obj.chunks():
f.write(chunk)
f.close()
return HttpResponse("上传成功!")

2. 案例:批量上传数据

1
2
3
4
5
<form method="post" enctype="multipart/form-data" action="/depart/multi/">
{% csrf_token %}
<input type="file" name="exc">
<input type="submit" value="上传">
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def depart_multi(request):
"""批量上传excel文件"""
# 1. 获取对象
file_obj = request.FILES.get("exc")
# 2. 将对象传递给 openpyxl,由 openpyxl读取文件的内容
wb = load_workbook(file_obj)
sheet = wb.worksheets[0]
# 3. 循环获取每一行的数据,排除第一行
for row in sheet.iter_rows(min_row=2):
text = row[0].value
# print(text)
# 加入到数据库
exists = models.Department.objects.filter(title=text).exists()
if not exists:
models.Department.objects.create(title=text)
return redirect("/depart/list/")

3. 混合数据上传(Form)

  • 提交页面时,用户输入数据+文件(输入不能为空、报错)
1
2
3
4
class UpForm(forms.Form):
name = forms.CharField(label="姓名")
age = forms.IntegerField(label="年龄")
img = forms.FileField(label="头像")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div class="panel panel-primary" style="width: 40rem;margin-top: 20px">
<div class="panel-heading">
<h3 class="panel-title">{{ title }}</h3>
</div>
<div class="panel-body">
<form method="post" enctype="multipart/form-data" novalidate>
{% csrf_token %}

{% for field in form %}
<div class="form-group">
<lable>{{ field.label }}: </lable>
{{ field }}
<span style="color: red">{{ field.errors.0 }}</span>
</div>
{% endfor %}

<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
</div>

3.1 创建一个数据库用来保存提交的数据

1
2
3
4
5
class Boss(models.Model):
"""演示上传文件"""
name = models.CharField(verbose_name="姓名", max_length=32)
age = models.IntegerField(verbose_name="年龄", default=0)
img = models.CharField(verbose_name="头像",max_length=128)

3.2 读取上传的文件内容,写入到文件夹中并获取文件路径,将路径保存到数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def upload_list(request):
"""===================Form操作====================="""
title = "Form上传"
if request.method == "GET":
form = UpForm()
return render(request, "upload_list.html", {"form": form, "title": title})
form = UpForm(data=request.POST, files=request.FILES)
if form.is_valid():
# 1.读取上传的文件内容,写入到文件夹中并获取文件路径
file_obj = form.cleaned_data.get("img")
db_file_path = os.path.join("static", "images", file_obj.name) # 在数据库中存储路径
file_path = os.path.join("app01", db_file_path)
f = open(file_path,"wb")
for chunk in file_obj.chunks():
f.write(chunk)
f.close()
# 2. 将文件路径保存到数据库
models.Boss.objects.create(
name=form.cleaned_data["name"],
age=form.cleaned_data["age"],
img=db_file_path,
)
return HttpResponse("...")
return render(request, "upload_list.html", {"form": form, "title": title})

4. media文件夹-存放用户上传文件

在urls.py 文件中进行配置

1
2
3
4
5
6
7
from django.urls import re_path
from django.views.static import serve
from day02 import settings

urlpatterns = [
re_path(r'media/(?P<path>.*)$',serve,{'document_root':settings.MEDIA_ROOT},name='media'),
]

settings.py中设置

1
2
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"

5. 混合数据上传(ModelForm)

  • models.py

    1
    2
    3
    4
    5
    6
    class City(models.Model):
    """演示上传文件(ModelForm版本)"""
    name = models.CharField(verbose_name="名称", max_length=32)
    count = models.IntegerField(verbose_name="人口", default=0)
    # FileField会自动保存文件路径到数据库,upload_to会将文件保存到相应路径
    img = models.FileField(verbose_name="Logo", max_length=128, upload_to='city/')
  • 定义ModelForm

    1
    2
    3
    4
    5
    class UpModelForm(BootStrapModelForm):
    boot_exclude = ['img']
    class Meta:
    model = models.City
    fields = "__all__"
  • 视图

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def upload_model_list(request):
    """上传数据(ModelForm版本)"""
    title = "ModelForm上传"
    if request.method == "GET":
    form = UpModelForm()
    return render(request,'upload_model_list.html',{"form":form, "title": title})
    form = UpModelForm(data=request.POST, files=request.FILES)
    if form.is_valid():
    form.save()
    return HttpResponse("上传成功")
    return render(request, 'upload_model_list.html', {"form": form, "title": title})