Django 更新文件到数据库

项目场景:

在Django的一个小项目中,对用户和课程数据进行增删改查,使用到了文件上传的方法


问题描述:

使用了文件上传到数据库的方法,上传各种文件都没问题,但是当我更新文件到数据库时,发现只能更新数据库中的路径,静态资源文件夹中却无法更新,明明和自己写的上传方法没任何区别,就是无法更新,介绍下如何上传文件:
1.肯定是设计数据库,设计的时候upload_to这个属性必须和自己静态文件夹内路径一致,因为我默然将用户资源文件都存放在Meida静态资源文件下,关于如何配置Media,我之前提过。
在这里插入图片描述
在这里插入图片描述
2.在前端文件中写好input输入框的类型(因为遇到问题是在图片上传上,这里只放上file上传的简单代码)


     <div class="form-group">
          <h4>文件备注:</h4>
          <input type="text" id="file_title" class="form-control"
                 name="file_title">

          <input type="file" id="file" name="file">
          <span id="result"></span>
      </div>
	
	{# js里面的代码是将所有控件的内容都获取下来,然后再使用Ajax传送到后端 #}
	
	     var formdata = new FormData();
            var request_data = $("#form").serializeArray();
            $.each(request_data, function (index, data) {
                formdata.append(data.name, data.value)
            });
            {#alert($("#file_title").val())#}
            formdata.append("file", $("#file")[0].files[0]);

            $.ajax({
                url: "",
                type: "post",
                contentType: false,
                processData: false,
                data: formdata,
                success: function (data) {
                    {#alert(data.user)#}
                    location.href = "/course_two/{{ course_id }}"
                }
            })
                                            

3.后端接收代码

 if request.is_ajax():
        form = InformationForm(request.POST)
        response = {"user": None, "msg": None}
        if form.is_valid():
            cour = Course.objects.filter(course_id=pk).first()
            teacher_id_id = cour.teacher_id_id
            # 生成一条用户纪录
            print("teacher_id_id", teacher_id_id)
            file_title = request.POST.get("file_title")
            file_upload = request.FILES.get("file")

            extra = {}
            if file_upload:
                extra["file_url"] = file_upload
                File.objects.create(teacher_id_id=teacher_id_id, file_title=file_title,
                                    course_id_id=pk, download_count=0, **extra)
### 上面是如何上传文件

原因分析:

在搜索了关键字upload_to之后发现,创建后会默认保存到相应的文件夹路径中去,但是没有说更新会保存,那既然这样就重新创建咯,不过这样有点点麻烦,因为用户表的字段比较多,既然是重新,又得更新一些数据,思路肯定是先取出来放字典里,再删除数据库信息,然后将前端传输过来的数据覆盖到字典里,最后将字典直接创建到数据库中。

重点:但是这是一种不周全的方法,如果没有主外键关系可以这样,如果有那只能另寻他路了


解决方案:

数据库ORM model.py里面还是这样的写法
在这里插入图片描述

前端如下:

<form id="form">
    <span class="error pull-right"></span>

    {% csrf_token %}
    <input type="text" id="pwd" class="form-control" placeholder="输入原密码">
    {% for field in c_form %}
        <div class="form-group">
            <label for="{{ field.auto_id }}" class="text">{{ field.label }}</label>
            {{ field }} <span class="error pull-right"></span>
        </div>
    {% endfor %}
    <div class="form-group">
        <label for="avatar" class="text">
            头像
            <img id="avatar_img" width="60" height="60" src="media/{{ control.avatar }}"
                 alt="">
        </label>
        <input type="file" id="avatar" name="avatar">
    </div>
    <div class="text-center">
        <button type="button" class="update_bt btn btn-primary">修改</button>

    </div>
</form>

   <script>
        // 头像预览
        $("#avatar").change(function () {
            var file_obj = $(this)[0].files[0];
            // 获取文件对象的路径
            var reader = new FileReader();
            reader.readAsDataURL(file_obj);
            // 修改img的src属性 ,src=文件对象的路径
            reader.onload = function () {
                $("#avatar_img").attr("src", reader.result)
            };

        });
        // 基于Ajax提交数据
        $(".update_bt").click(function () {
            //console.log($("#form").serializeArray());
            var formdata = new FormData();
            var request_data = $("#form").serializeArray();
            $.each(request_data, function (index, data) {
                formdata.append(data.name, data.value)
            });

            formdata.append("avatar", $("#avatar")[0].files[0]);
            formdata.append("pwd", $("#pwd").val());

            $.ajax({
                url: "",
                type: "post",
                contentType: false,
                processData: false,
                data: formdata,
                success: function (data) {
                    if (data.user) {
                        // 更新成功
                        location.href = "/login/"
                    } else { // 更新失败
                        console.log(data.msg)
                        $("span.error").html(data.msg);
                    }
                }
            })

        })
    </script>

后端的结果就是:

def update(request, pk, **kwargs):
    control = Control.objects.filter(id=pk).first()
    response = {"user": None, "msg": None}

    c_form = ControlForm(instance=control)
    # print(c_form)
    if request.method == 'POST' and request.is_ajax():
        # 如果密码正确
        if check_password(request.POST['pwd'], control.password):
            try:
                print(control.username, request.POST['username'])
                password = make_password(request.POST['password'])
                username = request.POST['username']
                email = request.POST['email']
                date_joined = str(request.POST['initial-date_joined']).split(" ")[0]
                telephone = request.POST['telephone']
                address = request.POST['address']
                controls = Control.objects.filter(id=pk)# 查询结果
                controls_li = controls.values_list()  # 将查询到的数据存下来,因为主键是惟一的,所以肯定只能查到一条
                control_dict = {}
                for i in controls_li: # 将遍历出来的数据放到键值对中,确保一一对应,直接去数据库把字段拿过来
                    control_dict['password'] = i[0]
                    control_dict['last_login'] = i[1]
                    control_dict['is_superuser'] = i[2]
                    control_dict['username'] = i[3]
                    control_dict['first_name'] = i[4]
                    control_dict['last_name'] = i[5]
                    control_dict['email'] = i[6]
                    control_dict['is_staff'] = i[7]
                    control_dict['is_active'] = i[8]
                    control_dict['date_joined'] = i[9]
                    control_dict['id'] = i[10]
                    control_dict['telephone'] = i[11]
                    control_dict['address'] = i[12]
                    control_dict['role'] = i[13]
                    control_dict['avatar'] = i[14]
                    control_dict['create_time'] = i[15]

                # 上面方法可能蠢了点,但是这是普通的我能想到的最直接的方法
                # 下面就是判断前端是否传输了这些字段过来,如果传了就更新键值对的值
                avatar_obj = request.FILES.get("avatar")
                if avatar_obj:
                    control_dict["avatar"] = avatar_obj
                if control.username != request.POST['username']:
                    control_dict["username"] = username
                if control.email != request.POST['email']:
                    control_dict["email"] = email
                if control.telephone != request.POST['telephone']:
                    control_dict["telephone"] = telephone
                if control.password != request.POST['password'] and request.POST['password']:
                    control_dict["password"] = password
                # 搞定之后就删除,然后重新根据保存好的键值对进行创建
                controls.delete()
                controls.create(**control_dict)
                response["user"] = request.POST['username']
                print('创建成功阿')
                return JsonResponse(response)

            except Exception as e:
                response["msg"] = "请输入手机号" + str(e)
                print(response["msg"], e)
                return JsonResponse(response)

        else:

            response["msg"] = "原密码不正确"
            # print(response["msg"])
            return JsonResponse(response)
    context = {
        'control': control,
        'c_form': c_form,
    }
    return render(request, 'lfh/update.html', context)

在这里插入图片描述

另一种解决思路:因为即使无法将结果传到后台,但是路径可以保存到数据库,那我们在保存到数据库之前,将图片保存到相应的路径中,就可以解决这种情况了。

 if request.method == 'POST' and request.is_ajax():
        # 如果密码正确
        if check_password(request.POST['pwd'], control.password):
            # print("*")
            try:
                print(control.username, request.POST['username'])

                password = make_password(request.POST['password'])

                username = request.POST['username']

                email = request.POST['email']
                date_joined = str(request.POST['initial-date_joined']).split(" ")[0]
                telephone = request.POST['telephone']
                address = request.POST['address']
                # get的东西无法使用update
                controls = Control.objects.filter(id=pk)
                ddd = 'media' + os.path.join(os.path.join('media', 'avatars'), str(course[0].course_avatar))
            	os.remove(ddd)
                # controls_li = controls.values_list()
                # print("---" * 19)
                # control_dict = {}
                # for i in controls_li:
                #     control_dict['password'] = i[0]
                #     control_dict['last_login'] = i[1]
                #     control_dict['is_superuser'] = i[2]
                #     control_dict['username'] = i[3]
                #     control_dict['first_name'] = i[4]
                #     control_dict['last_name'] = i[5]
                #     control_dict['email'] = i[6]
                #     control_dict['is_staff'] = i[7]
                #     control_dict['is_active'] = i[8]
                #     control_dict['date_joined'] = i[9]
                #     control_dict['id'] = i[10]
                #     control_dict['telephone'] = i[11]
                #     control_dict['address'] = i[12]
                #     control_dict['role'] = i[13]
                #     control_dict['avatar'] = i[14]
                #     control_dict['create_time'] = i[15]

                # 存入文件夹
                avatar_obj = request.FILES.get("avatar")
                extra = {}
                # if avatar_obj:
                #     control_dict["avatar"] = avatar_obj
                # if control.username != request.POST['username']:
                #     control_dict["username"] = username
                # if control.email != request.POST['email']:
                #     control_dict["email"] = email
                # if control.telephone != request.POST['telephone']:
                #     control_dict["telephone"] = telephone
                # if control.password != request.POST['password'] and request.POST['password']:
                #     control_dict["password"] = password
                if avatar_obj:
                    extra["avatar"] = '/avatars/' + str(avatar_obj)
                img = request.FILES.get("avatar")
                old_name = img.name
                dir = os.path.join(os.path.join('media', 'avatars'), str(old_name))
                print(dir, "---------------")
                destination = open(dir, 'wb+')
                for chunk in img.chunks():
                    destination.write(chunk)
                destination.close()
                if control.username != request.POST['username']:
                    extra["username"] = username
                if control.email != request.POST['email']:
                    extra["email"] = email
                if control.telephone != request.POST['telephone']:
                    extra["telephone"] = telephone
                if control.password != request.POST['password'] and request.POST['password']:
                    extra["password"] = password
                # controls.delete()
                controls.update(**extra)
                response["user"] = request.POST['username']
                print('创建成功阿')
                return JsonResponse(response)

            except Exception as e:
                response["msg"] = "请输入手机号" + str(e)
                print(response["msg"], e)
                return JsonResponse(response)

        else:

            response["msg"] = "原密码不正确"
            # print(response["msg"])
            return JsonResponse(response)
    context = {
        'control': control,
        'c_form': c_form,
    }
    return render(request, 'lfh/update.html', context)
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值