django实现文件上传

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

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

1、自己手写

先写一个上传的页面 upload_file.html
enctype="multipart/form-data 一定要加这个,不然只会上传文件名,不会上传文件内容。

{% 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 请求,就将获取到的文件对象在项目跟目录创建一个相同的文件名保存起来。

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 中创建一个数据库

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)

视图函数

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 文件内容:

{% 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中的配置
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中配置:

import os

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

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

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目录,并且把文件路径保存到数据库

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

{% 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 %}

效果:
在这里插入图片描述
数据库存储的:
在这里插入图片描述

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

javascript_good

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值