django实现文件上传

在django中实现文件上传有三种方法可以实现:

  • 自己手动写
  • 使用Form组件
  • 使用ModelForm组件
    其中使用ModelForm组件实现是最简单的。

1、自己手写

先写一个上传的页面 upload_file.html

enctype="multipart/form-data 一定要加这个,不然只会上传文件名,不会上传文件内容。

html 复制代码
{% extends 'layout.html' %}

{% block content %}
    <div class="container">
       <form method="post" enctype="multipart/form-data">
           {% csrf_token %}
            <input type="text" name="username">
           <input type="file" name="avatar">
           <input type="submit" value="提交">
       </form>

    </div>

{% endblock %}

在写一个视图函数:

在这个视图函数中如果是get 请求就展示上传的页面,如果是post 请求,就将获取到的文件对象在项目跟目录创建一个相同的文件名保存起来。

python 复制代码
from django.shortcuts import render, HttpResponse

def upload_list(request):
    if request.method == 'GET':
        return render(request,'upload_file.html')

    print(request.POST)   # 请求体中的数据
    print(request.FILES)  # 请求发过来的文件 {}

    file_object = request.FILES.get("avatar")
    f = open(file_object.name,mode='wb')
    for chunk in file_object.chunks():
        f.write(chunk)

    f.close()
    return HttpResponse('上传成功')

简单的页面效果:

2、使用Form组件

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

  • Form生成HTML标签 :type=file
  • 表单的验证
  • form.cleaned_data 获取数据 + 文件对象

将上传的图片保存到static目录,并且在数据库保存文件存储的路径

models.py 中创建一个数据库

python 复制代码
class Boss(models.Model):
    """保存图片"""
    name = models.CharField(verbose_name="姓名",max_length=32)
    age = models.IntegerField(verbose_name="年龄")
    img = models.CharField(verbose_name="图片",max_length=128)

视图函数

python 复制代码
from django.shortcuts import render, HttpResponse
from django import forms
import os
from app01 import models

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

def upload_form(request):
    if request.method == 'GET':
        form = UpForm()
        return render(request,'upload_form.html',{'form':form})

    form = UpForm(data=request.POST,files=request.FILES)
    if form.is_valid():
        # 1、读取图片内容,写入文件夹中并获取文件的路径
        image_object = form.cleaned_data.get('img')

        # 创建文件路径
        db_file_path = os.path.join('static','img',image_object.name)

        file_path = os.path.join('app01',db_file_path)
        f = open(file_path,mode='wb')
        for chunk in image_object.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_form.html',{'form':form})

upload_form.html 文件内容:

html 复制代码
{% extends 'layout.html' %}

{% block content %}
    <div class="container">
         <div class="panel panel-default">
            <div class="panel-heading">图片上传</div>
            <div class="panel-body">
               <form  method="post"  enctype="multipart/form-data"  novalidate>
                    {% csrf_token %}
                    {% for field in form %}
                      <div class="form-group">
                        <label >{{ field.label }}</label>
                        {{ field }}
                         <span style="color:red">{{ field.errors.0 }}</span>
                      </div>
                    {% endfor %}
                      <button type="submit" class="btn btn-primary">提交</button>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

页面效果:

3、使用ModelForm组件

使用ModelForm的前提条件要设置好media 目录

启用media 目录

在django的开发中有两个特殊的文件夹:

  • static , 存放静态文件的路径,包括: css、js 、项目图片。
  • media , 用户上传的数据目录。
    1、在urls.py中的配置
python 复制代码
from django.urls import path,re_path
from django.views.static import serve
from django.conf import settings

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

2、在settings.py中配置:

python 复制代码
import os

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

models.py 重新创建一个表来存储文件路径

python 复制代码
class City(models.Model):
    """城市"""
    name = models.CharField(verbose_name="名称",max_length=32)
    count = models.IntegerField(verbose_name="人口")

    # 本质上数据库也是charField ,自动保存数据,upload_to 表示会保存到media目录下的city
    img = models.FileField(verbose_name='Logo',max_length=128,upload_to='city/')

视图函数:

通过 form.save() django 自动将文件存储到media目录下的city目录,并且把文件路径保存到数据库

python 复制代码
from django.shortcuts import render, HttpResponse
from app01 import models
from app01.utils.bootstrap import BootStrapModelForm

class UploadModelForm(BootStrapModelForm):
    bootstrap_exclude_name = ['img']
    class Meta:
        model = models.City
        fields = "__all__"

def upload_modelform(request):
    if request.method == 'GET':
        form = UploadModelForm()
        return render(request,'upload_form.html',{'form':form})

    form = UploadModelForm(data=request.POST,files=request.FILES)
    if form.is_valid():
        form.save()
        return HttpResponse('上传成功')
    return render(request, 'upload_form.html', {'form': form})

upload_form.html

html 复制代码
{% extends 'layout.html' %}

{% block content %}
    <div class="container">
         <div class="panel panel-default">
            <div class="panel-heading">图片上传</div>
            <div class="panel-body">
               <form  method="post"  enctype="multipart/form-data"  novalidate>
                    {% csrf_token %}
                    {% for field in form %}
                      <div class="form-group">
                        <label >{{ field.label }}</label>
                        {{ field }}
                         <span style="color:red">{{ field.errors.0 }}</span>
                      </div>
                    {% endfor %}
                      <button type="submit" class="btn btn-primary">提交</button>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

效果:

数据库存储的:

相关推荐
云和数据.ChenGuang1 小时前
Django 应用安装脚本 – 如何将应用添加到 INSTALLED_APPS 设置中 原创
数据库·django·sqlite
woshilys1 小时前
sql server 查询对象的修改时间
运维·数据库·sqlserver
Hacker_LaoYi1 小时前
SQL注入的那些面试题总结
数据库·sql
建投数据2 小时前
建投数据与腾讯云数据库TDSQL完成产品兼容性互认证
数据库·腾讯云
Hacker_LaoYi3 小时前
【渗透技术总结】SQL手工注入总结
数据库·sql
岁月变迁呀3 小时前
Redis梳理
数据库·redis·缓存
独行soc3 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
你的微笑,乱了夏天4 小时前
linux centos 7 安装 mongodb7
数据库·mongodb
工业甲酰苯胺4 小时前
分布式系统架构:服务容错
数据库·架构
独行soc5 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘