django实现类似admin后台上传文件的方法

在项目过程中,也许我们需要上传一张图片,或者需要上传一份文件,那么有什么方式既简单又有效呢,使用django该怎么做呢?

本文是自己在开发中有需要摸索出来的,使用了REST-framework如果有更好的方式,烦请留言相告,不胜感激!!

前端使用input标签选择文件,后端接受post请求上传文件,以文件流的方式保存文件。文件路径在settings.py配置

1、django的安装启动就不在赘述了

2、 在settings.py配置上传的路径

FILE_URL = "static/%Y/%m/files/"  # 例如将文件放在项目目录下的static/2018/12/files/下(将在代码中做格式化)
FILE_ROOT = os.path.join(BASE_DIR, FILE_URL)  # 文件目录绝对路径

2、创建好模型

用户模型也不再赘述了。可以使用自带的认证用户模型。

class File(BaseModel):
    # upload_to参数是后台admin上传图片的保存位置,我们后续自己写的接口,图片也保存在这个位置
    file = models.FileField(upload_to=settings.FILE_URL, verbose_name="文件选择")
    name = models.CharField(max_length=200, blank=True, verbose_name="文件名称")

    class Meta:
        db_table = 'test_file'
        verbose_name = "文件"
        verbose_name_plural = verbose_name

    def __str(self):
        return self.name

3、迁移数据库,在项目目录下使用命令

python manage.py createsuperuser

创建好admin超级用户。(本来是无需创建的,这里只是为了做测试)

4、 在当前应用app下的admin.py注册模型

from django.contrib import admin
from .models import File

admin.site.register(File)

5、python manage.py runserver 开启django服务器,打开默认网址127.0.0.1:8000/admin,登录admin超级管理员,就可以看到

点击模型,增加文件。保存。查看数据库,会发现

超级管理员是好办,已经完成了,文件就在项目目录下的static/2018/12/files/下。

可是我们的重点是自己实现这个过程,前端页面自己写上传来的。啰嗦了好久,进入正题!

在app下的views.py写好后端接口

import os
import datetime

from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response

from .serializers import FileSerializer
from .models import File


class FileView(APIView):
    def get(self, request):
        """获取指定id的文件,前端传入id"""
        file_id = request.GET.get("id")
        try:
            file = File.objects.get(id=int(file_id))  # 查询
        except Exception as e:
            return Response({"file": '', 'error': 'file does not exist'})
        serializer = FileSerializer(instance=file)  # 返回数据的序列化器
        return Response(serializer.data)

    def post(self, request):
        """上传文件的接口"""
        file_obj = request.FILES.get('file')  # 获取前端的文件
        file_uuid = request.POST.get('uuid')  # uuid
        file_name = file_uuid + file_obj.name  # 重新组成file_name
        time = datetime.datetime.now()
        file_root = time.strftime(settings.FILE_ROOT)  # 格式化保存路径
        if os.path.exists(file_root):
            pass
        else:
            os.makedirs(file_root)  # 路径不存在就建立文件夹
        file_path = os.path.join(file_root, file_name)  # 文件路径
        f = open(file_path, 'wb')
        # 写入保存上传的文件
        for chunk in file_obj.chunks():
            f.write(chunk)
        f.close()
        file_url = time.strftime(settings.FILE_URL) + file_name
        file = File.objects.create(
            file=file_url,
            name=file_obj.name,
        )
        file.save()
        return Response({"status": "upload success!", "file": file_url})  # 成功返回状态及文件的路径

配置好后端访问的urls

from django.urls import path
from . import views

urlpatterns = [
    path(r'file/', views.FileView.as_view())
]

# 这是app下的url,项目的url请自行喜欢配置哈

补充序列化器serialisers.py:

from rest_framework import serializers
from .models import File


class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model = File
        fields = '__all__'

6、写好前端html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传文件</title>
    <link rel="stylesheet" href="css/upload_file.css">
    <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
{#    配置后端的接口域名host.js文件内容就一行#}
{#    var host = "http://127.0.0.1:8000/";#}
    <script type="text/javascript" src="js/host.js"></script>
    <script type="text/javascript" src="js/upload_file.js"></script>
</head>
<body>

<div class="uploadFile">
    <input type="file" id="upFile">
    <input type="button" value="上传" id="fileSubmit" style="display: block; margin-top: 10px">
</div>
</body>
</html>

7. uplode_file.js

$(function(){
    // 点击上传按钮触发上传事件,如果想选择好文件就上传可以使用$("#upFile").change()函数
    $("#fileSubmit").click(function(){
        var formData = new FormData();
        var file = $("#upFile").get(0).files[0];  // 获取input选入的文件内容
        var uuid = generateUUID();  // 生成uuid
        formData.append('file', file);  // 加入数据表单
        formData.append('uuid', uuid);  // 传入uuid
        $.ajax({
            url: 'http://127.0.0.1:8000/file/',  // 后端django接口
            type: "POST",
            data:formData,
            processData: false,
            contentType: false,
            success: function(data){
                alert("success!");
            },
            error: function(e){
                alert("网络错误,请稍后再试!\n")
            }
        })
    });
    // 生成唯一的uuid,上传相同的文件一样保存
    function generateUUID() {
        var d = new Date().getTime();
        if(window.performance && typeof window.performance.now === "function"){
            d += performance.now(); //use high-precision timer if available
        }
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = (d + Math.random()*16)%16 | 0;
            d = Math.floor(d/16);
            return (c=='x' ? r : (r&0x3|0x8)).toString(16);
        });
        return uuid;
    }
})

最后!运行django服务器,开启前端页面,选择文件,上传。

成功后会在项目目录下生成static文件夹。一层层进里面就躺着我们上传的文件啦!

打开数据库查看,file字段与我们后台admin配置的upload_to上传的一样。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值