Django 文件上传

文件上传是一种很常见的需要,在django中也是如此,比如用户头像。但是文件上传又分不同情况下的文件上传.

      一种基于form表单file type,此时需要指定model中对应字段的upload路径。后台获取前端的数据后将文件路径保存到数据库,文件内容保存在upload指定的文件夹中。

     另一种则是基于原生js的FormData(ajax本身好像不能传文件对象,目前没找到方法,知道的望告知), FormData传递文件对象,并通过XMLHttpRequest将页面全部信息传递到后端views中,后台读取文件内容并写入指定路径的指定文件中。如果前端需要地址,则需要在后台获取到文件地址后返回给前端。

基于原生js的文件上传:

index.html

因为使用FormData(),contentType, processData一定要设置为False

<!DOCTYPE html>
{% load staticfiles %}
<html>
<body>
<p>请输入两个数字</p>
<form action="" method="get" enctype="multipart/form-data">
    {% csrf_token %}
    a: <input type="text" id="a" name="a"> <br>
    b: <input type="text" id="b" name="b"> <br>
    头像:<input type="file" id="file" name="file"><br>
    <p>a +b: <span id='result'></span></p>
    <button type="button" id='sum'>提交</button>
</form>

<script src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
<script>
    $(document).ready(function () {
        var form_data = new FormData(); //创建FormData对象
        $("#sum").click(function () {
            var a = $("#a").val();
            var b = $("#b").val();
            var file = $("#file")[0].files[0];  //获取文件对象,

            form_data.append('a', a);
            form_data.append('b', b);
            form_data.append('file', file);
            form_data.append('csrfmiddlewaretoken', "{{ csrf_token }}"); //带上csrf_token

            $.ajax(
                {
                    url: "{% url 'show' %}",
                    method: 'POST',

                    contentType: false,
                    processData: false,
                    data: form_data,
                    success: function (ret) {
                        $('#result').html(ret); //将计算结果填到标签内
                    }
                }
            )
        });
    });
</script>
</body>
</html>

views.py

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.

def show(request):
    if request.is_ajax():
        a = int(request.POST.get('a'))
        b = int(request.POST.get('b'))
        res = a + b
        file = request.FILES.get('file')
        file_name = file.name # file 自带的属性,name
        with open(file_name, 'wb') as f:
            for line in file:
                f.write(line)
        return HttpResponse(res)
    else:
        return render(request, 'index.html')

此时提交后,因为没有指定保存文件的路径,所以就在项目的要目录下。

基于Django的简单文件上传

userinfo.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户信息</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="text" name="username">
    <input type="file" name="file">
    <input type="submit" value="提交">
</form>
</body>
</html>

views.py

这里只简单的获取文件对象并写入文件,保存在根目录, file.chunks() 是将文件分割成块,内置方法。

def upload_file(request):
    if request.method == 'GET':
        return render(request, 'userinfo.html')
    elif request.method == 'POST':
        # 获取file文件名
        file = request.FILES.get('file')
        with open(file.name, 'wb') as f:
            for chunk in file.chunks():
                f.write(chunk)
    return HttpResponse('ok')

基于Django form表单的文件上传

这里用到了modelform

forms.py

from django import forms

from .models import User

class UserModelForm(forms.ModelForm):
    class Meta:
        model = User
        fields = '__all__'

models.py

from django.db import models

class User(models.Model):
    username = models.CharField(verbose_name='用户名', max_length=32)
    avatar = models.ImageField(verbose_name='头像', upload_to='uploads/')

这里注意要指定upload_to属性,即上传到哪个文件夹。

views.py

from django.shortcuts import render, HttpResponse
from django.views import View

from .forms import UserModelForm


class UploadFileView(View):
    def get(self, request):
        return render(request, 'userinfo.html')

    def post(self, request):
        avatar_form = UserModelForm(request.POST, request.FILES)
        if avatar_form.is_valid():
            avatar_form.save()
            return HttpResponse('success')
        else:
            return HttpResponse('failed')

注意这里UserForm中要添加第二个参数:request.FILES, 因为文件对象在request.FILES中而不在request.POST中。

这样在前端提交后,文件被保存在uploads文件夹中。

 

 

上一篇:Django cookie session

下一篇:Python 装饰器