美文网首页常见用法
django上传图片前后端实例

django上传图片前后端实例

作者: bigpangl | 来源:发表于2017-11-01 22:17 被阅读0次
    相关阅读

    JQuery Ajax使用FormData对象上传文件 图片 | CSDN
    Django 图片上传、存储与显示 | 博客园
    Bootstrap Modals(模态框) | 菜鸟教程
    JQuery 往textarea中光标所在位置插入文本 | CSDN
    Django 设置media static | 博客园

    前后花了快5,6个小时,期间搜索了很多东西,才勉强完成这个功能,推荐阅读有遗漏

    需求

    概述:给一个页面,添加一个图片上传的功能

    详细描述
    • 页面添加按钮,当点击按钮时,弹出上传图片的框
    • 选中需要上传的图片,提交,后端返回浏览器可查看图片的url
    • 退出显示的框,在此前文本编辑的部分,光标选中处,插入markdown的格式,要求能够在转为html后正常显示图片

    大致要实现简书的markdown的编辑器功能,当然,直接粘贴上传图片难度系数未知,方式未知,只有想着通过按钮上传

    思路步骤
    • 编辑前端html和jquery,完成点击弹出框(bootstrap模态框),选择图片(form标签中 input标签,type属性为 file,accppt属性限制图片类型)图片信息从前端到后端(ajax发送post发送formData)
    • django接收处理图片信息(myfile = request.File.get('name',None),myfile.read() 二进制数据,myfile._name 文件名,os.path.splitext()[1]扩展类型),保存(with open rb)并按照预设返回HttpResponse(jsondata,content_type="application/json")
    • 收到成功的信息后,进行页面上变动,如何让框隐藏下去(模态框hide),同时,在之前的编辑位置,即光标处(拿来insertContent),插入文本
    遇到的问题
    • 通过什么上传
      通过html中form标签,input的type类型选择file,即上传文件的选择框,同时通过accept="image/*"限制只能选择图片
      再通过绑定form的sumbit事件,在自定义的sumbit事件中,完成以post方式,formdata形式上传图片

    我是首先通过原有项目的一处上传文件的html结构,照搬过来,同时了解它在我需要的位置有什么样的作用,根据有的代码关键词,网上搜索先关帖子,然后去修改。才发现此处用到了bootstrap,一个后端工程师用来制作简单前端效果的东西。

    <!-- 图片上传部分 -->
        <div class="col-center-block col-lg-10" style="margin-top:60px; margin-bottom: 10px;text-align: right">
            <button type="submit" data-toggle="modal" data-target="#myModal" class="btn  btn-default btn-sm float-right">
                上传图片
            </button>
        </div>
        
        <!-- 上为按钮,下为弹框 -->
        
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
            <div class="modal-dialog modal-sm" role="document">
                <div class="modal-content upload_div">
                    <form id="uploadForm">
                        {% csrf_token %}
                        <div class="form-group">
                            <input type="file" name="teamFile" accept="image/*">
                        </div>
                        <div class="form-group" role="group" aria-label="...">
                            <input type="submit" class="btn  btn-default col-lg-12">
                        </div>
                        <div class="clear">&nbsp;</div>
                    </form>
                </div>
            </div>
        </div>
    
    <!-- 图片上传部分 -->
    
    <script type="text/javascript">
        (function($){
            $.fn.insertContent = function(myValue, t) {
                var $t = $(this)[0];
                if (document.selection) {
                    this.focus();
                    var sel = document.selection.createRange();
                    sel.text = myValue;
                    this.focus();
                    sel.moveStart('character', -l);
                    var wee = sel.text.length;
                    if (arguments.length == 2) {
                        var l = $t.value.length;
                        sel.moveEnd("character", wee + t);
                        t <= 0 ? sel.moveStart("character", wee - 2 * t - myValue.length) : sel.moveStart("character", wee - t - myValue.length);
                        sel.select();
                    }
                } else if ($t.selectionStart || $t.selectionStart == '0') {
                    var startPos = $t.selectionStart;
                    var endPos = $t.selectionEnd;
                    var scrollTop = $t.scrollTop;
                    $t.value = $t.value.substring(0, startPos) + myValue + $t.value.substring(endPos, $t.value.length);
                    this.focus();
                    $t.selectionStart = startPos + myValue.length;
                    $t.selectionEnd = startPos + myValue.length;
                    $t.scrollTop = scrollTop;
                    if (arguments.length == 2) {
                        $t.setSelectionRange(startPos - t, $t.selectionEnd + t);
                        this.focus();
                    }
                }else {
                    this.value += myValue;
                    this.focus();
                }
            };
        })(jQuery);
        
        //上面为在textarea中光标位置处插入文本的插件?方法?,下为自定义sumbit
        
        $(function(){
            $('#uploadForm').submit(function(){
                var data = new FormData($('#uploadForm')[0]);
                $.ajax({
                    url: './uploadmarkimage',
                    type: 'POST',
                    data: data,
                    dataType: 'JSON',
                    cache: false,
                    processData: false,
                    contentType: false,
                    success:function(data){
                        if(data.code==0){
                            var filename = data.msg.filename;
                            var url = data.msg.url;
                            var imgstr = "![]("+url+")";
                            var addstr = $("textarea[name='content']").val()+imgstr;
                            $("textarea[name='content']").insertContent(imgstr);
                            $("#myModal").modal('hide');
                        }else{
                            alert("上传失败,请稍后再试");
                        }
                    },
                    error: function (data) {
                        alert("网络错误");
                    }
                });
                return false;
            });
        });
    </script>
    

    此部分多来自别人帖子分享

    • 如何实现点击时弹出
      这是bootstrap里面的模态框的使用方法,即``data-toggle="modal" data-target="#myModal"`的用法,仅抄袭得来,最初不知道

    • django如何接收
      试图寻找django接受formdata的方式,因为我认为上传的方式不同,那么接受方式也应该不同,比如,是在request.POST中还是request.FILES中,没有找到现成的,自己的摸索花了些时间

    import uuid
    import os
    import json
    
    def uploadimage(request):
        if request.method == 'POST':
            myfile = request.FILES.get('teamFile',None)
            filename = str(uuid.uuid1())+os.path.splitext(myfile._name)[1]
            savename = os.path.join(os.getcwd(),'teamdoc')
            savename = os.path.join(savename,'uploadFile')
            savename = os.path.join(savename,filename)
            code = 1000
            if myfile:
                with open(savename,'wb') as file:
                    file.write(myfile.read())
                code = 0
            else:
                filename=''
            jsondata =json.dumps({"code":code,"msg":{"url":'/uploadFile/%s'%(filename),'filename':myfile._name}})
            return HttpResponse(jsondata,content_type="application/json")
    
    • 如何上传完后不刷新页面
      在别人的分享中,发现,加入return false后,自动跳转的现象消失

    • 如何隐藏弹框
      弹框,更标准的叫法是,模态框,是在我询问了别人之后得到的(一开始不知道这是bootstrap的内容,而且连bootstarp都不知道)。通过bootstrap的模态框用法可以找到隐藏函数,``$("#myModal").modal('hide')`

    • 如何在光标处插入文本
      拿来主义。已有现成的,可以当做一个函数用的东西,在网上找到,也就是上面的form sumbit事件上的function,使用的时候通过$("textarea[name='content']").insertContent(imgstr)插入imgstr信息

    • 如何让返回的url可显示图片信息
      django的media路径设置,一方面,在django中设定media文件的存放位置,比如磁盘的某个文件夹下,即MEDIA_ROOT,在setting.py中设置。同时在最外层的项目的url.py中,设定media访问的url地址,并将这个地址和我们设定的磁盘上的位置关联起来

    # setting.py
    PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
    MEDIA_ROOT = os.path.join(PROJECT_PATH, 'uploadFile/').replace('\\', '/')
    
    # urls.py
    url(r'^uploadFile/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT})
    

    然后浏览器通过 http://127.0.0.1:81/uploadFile/xxxx.jpg 就可以加载,虽说也有配置MEDIA_URL,但此时这种配置,已经满足了需要似的,对media的配置还够透彻

    相关文章

      网友评论

        本文标题:django上传图片前后端实例

        本文链接:https://www.haomeiwen.com/subject/nydnpxtx.html