• django-附件上传、media、extra、事务


    1 普通上传

    1.1 html

    <form action="/index/" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <p><input type="text" name="user" id="user"></p>
        <p><input type="file" name="myFile" id="file"></p>
        <input type="submit">
    </form>

    1.2 views

    def index(request):
        if request.method == "POST":
            print(request.POST)
            print(request.FILES)
            file_obj = request.FILES.get("myFile")
            print(file_obj.name)
    
            with open(file_obj.name,"wb") as f:
                for line in file_obj:
                    f.write(line)
    
            return HttpResponse("上传成功。")
        return render(request, "index.html")

    2 基于ajax实现

    2.1 Html

    <p><input type="file" name="myFile" id="file"></p>
    {% csrf_token %}
    <button>ajaxSend</button>
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
    <script>
        $("button").click(function () {
            var formdata = new FormData();
            formdata.append("imgFile", $("#file")[0].files[0]);
            formdata.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
            $.ajax({
                url: "/upload_img/",
                type: "POST",
                data: formdata,
                processData: false,
                contentType: false,
                success: function (msg) {
                    console.log(msg)
                }
            })
        })
    </script>

    2.2 views

    import os,json
    def upload_img(request):
        if request.is_ajax():
            obj = request.FILES.get("imgFile")
            img_path = os.path.join("static","img",obj.name)
            with open(img_path,mode="wb") as f:
                for chunk in obj.chunks():
                    f.write(chunk)
            data = {
                "status" : True,
                "path" : img_path
            }
            return HttpResponse(json.dumps(data))

    3 伪ajax上传

      基于FormData
      缺点:兼容性不好
      优点:Ajax直接发送
      伪Ajax,兼容性更好
        iframe,天生局部刷新
        form,天生整个页面刷新

    3.1 html

    <input type="text" placeholder="默认值看看刷新之后在不在" />
    <form method="POST" target="uploadIframe" action="/upload_img2/" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="text" name="user" />
        <a class="add-pub-btn pub-icons">
            上传
            <input type="file" name="avatar" id="imgUrl" />
        </a>
        <input type="submit" value="提交" />
    </form>
    <iframe id="ifm" name="uploadIframe" onload="successCallback(this);" style="display: none;" ></iframe>
    <div id="imgList"></div>
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
    <script>
        function successCallback(ths){
            var response = ths.contentWindow.document.body.innerHTML;
            response = JSON.parse(response);
            console.log(response);
            var img = document.createElement('img');
            img.src = "/" + response.data;
    
            $('#imgList').append(img);
        }
    </script>

    3.2 views

    def upload2(request):
        return render(request,"iframe_upload.html")
    
    def upload_img2(request):
        response = BaseResponse()
        try:
            obj = request.FILES.get("avatar")
            img_path = os.path.join("static","img",obj.name)
            with open(img_path,mode="wb") as f:
                for chunk in obj.chunks():
                    for chunk in obj.chunks():
                        f.write(chunk)
        except Exception as e:
            response.msg = str(e)
        else:
            request.status = True
            response.data = img_path
        return HttpResponse(json.dumps(response.get_dict()))

    4 上传按钮美化

    4.1 css

    <style>
        .add-pub-btn {
            width: 62px;
            height: 31px;
            line-height: 31px;
            display: block;
            text-align: center;
            color: #fff;
            font-size: 14px;
            font-weight: 700;
            margin-top: 5px;
            cursor: pointer;
        }
        .pub-icons {
            background: url(/static/img/bottom.png?v=2.8) no-repeat 0 0;
        }
        #imgUrl {
            border: 0;
            filter: alpha(opacity=0);
            background: 0 0;
            opacity: 0;
            -moz-opacity: 0;
            width: 62px;
            height: 31px;
            left: 5px;
            top: 5px9;
            position: absolute;
            cursor: pointer;
        }
    </style>

    4.2 按钮设置

    <a class="add-pub-btn pub-icons">
        上传
        <input type="file" name="avatar" id="imgUrl" />
    </a>

    5 图片预览

    本图片的预览功能,主要利用html.js的FileReader进行实现的

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>注册</title>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <style>
            #avatar {
                margin-top: 5px;
                margin-bottom: 5px;
                position: relative;
                width: 100px;
                height: 100px;
            }
    
            #avatar_img, #file {
                width: 100px;
                height: 100px;
                position: absolute;
                left: 15px;
                top: 0;
            }
    
            #file {
                opacity: 0;
            }
        </style>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-8" id="avatar">
                <img src="default.png" class="img-thumbnail" id="avatar_img">
                <input type="file" id="file">
            </div>
        </div>
    </div>
    
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
    <script type="text/javascript">
        // 预览功能
        $("#file").change(function () {
            var choose_file = $("#file")[0].files[0];
            var reader = new FileReader();
            reader.readAsDataURL(choose_file);
            reader.onload = function () {
                $("#avatar_img").attr("src", this.result)
            }
        });
    </script>
    
    </body>
    </html>

    6 文件上传路径

    6.1 配置
    在settings中配置

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

    在urls.py中配置

    from django.views.static import serve
    
    url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),

    6.2 使用

    <img src='/media/avatarDir/a.png'>

    7 extra

      有些情况下,Django的查询语法难以简单的表达复杂的 WHERE 子句,对于这种情况, Django 提供了 extra() QuerySet修改机制 — 它能在 QuerySet生成的SQL从句中注入新子句
    extra可以指定一个或多个 参数,例如 select, where or tables. 这些参数都不是必须的,但是你至少要使用一个!要注意这些额外的方式对不同的数据库引擎可能存在移植性问题.(因为你在显式的书写SQL语句),除非万不得已,尽量避免这样做

    # in sqlite:
        article_obj=models.Article.objects
                  .filter(nid=1)
                  .extra(select={"standard_time":"strftime('%%Y-%%m-%%d',create_time)"})
                  .values("standard_time","nid","title")
        print(article_obj)
        # <QuerySet [{'title': 'MongoDb 入门教程', 'standard_time': '2017-09-03', 'nid': 1}]>
    current_user = models.UserInfo.objects.filter(username=username).first()   #当前用户
    【每一步的分析过程】
    1、models.Article.objects.all()  #查出每一篇文章
    2、models.Article.objects.all().filter(user=current_user)  #查出当前用户的所有文章
    3、models.Article.objects.all().filter(user=current_user).extra(select={"filter_create_date":"strftime('%%Y/%%m',create_time)"}).values_list("filter_create_date")
    #查出当前用户的所有文章的create_time,并且只取出年份和月份
    解决方案:使用extra方法 
    extra使用来进行过滤的,参数select必须等于一个字典(转成sql的where语句去执行,查出create_time,然后转换成自己格式化的时间)
    4、models.Article.objects.all().filter(user=current_user).extra(select={"filter_create_date":"strftime('%%Y/%%m',create_time)"}).values_list("filter_create_date").annotate(Count("title"))
    #按照查询出来的年份和月份进行分组,并且显示文章个数

    8 事务使用

    from django.contrib.auth import authenticate
    with transaction.atomic():
        models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id)
        models.Article.objects.filter(nid=article_id).update(up_count=F("up_count") + 1)
  • 相关阅读:
    APICloud联合腾讯云推出“云主机解决方案“,各种福利等你拿
    WiFi模块Demo(新手教程)图文详解模块使用教程
    移动APP 微信支付完整过程(wxPay 方案一)
    APICloud开发者进阶之路 | txLive模块(直播类)试用分享
    解决R语言临时文件目录的问题(tempdir、tempfile)
    CentOS下SparkR安装部署:hadoop2.7.3+spark2.0.0+scale2.11.8+hive2.1.0
    Extending sparklyr to Compute Cost for K-means on YARN Cluster with Spark ML Library
    Running R jobs quickly on many machines(转)
    R语言快速深度学习进行回归预测(转)
    sparklyr包:实现Spark与R的接口
  • 原文地址:https://www.cnblogs.com/goodshipeng/p/8033364.html
Copyright © 2020-2023  润新知