• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Django+小程序实现图片上传功能

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一、先完成Django部分

  1、先定一个类来完成图片功能,简单来说:在浏览器上只给图片名,直接返回图片(这里的类我取名为“ImageView”,注:这个ImageView类所在的路径是resources文件中的images文件),具体操作如下:

  (1)先在settings中配置图片路径,配置如下:

#配置图片路径
RESOURCES_DIR = os.path.join(BASE_DIR,'resources')
IMAGES_DIR = os.path.join(RESOURCES_DIR,'images')

  

  (2)再定一个文件,取名为“utils”,在utils文件中创建response.py的python文件,接下来再配置response.py,具体配置如下:

    展示所创建的response.py,如下:

    

 

    之后,再配置response.py,配置如下:

# 状态码
class ReturnCode:
    SUCCESS = 0

    FAILED = -100
    WRONG_PARMAS = -101
    RESOURCE_NOT_FOUND = -102

    UNAUTHORIZED = -500
    BROKEN_AUTHORIZED_DATA = -501

    @classmethod
    def message(cls, code):
        if code == cls.SUCCESS:
            return 'success'
        elif code == cls.FAILED:
            return 'failed'
        elif code == cls.UNAUTHORIZED:
            return 'unauthorized'
        elif code == cls.WRONG_PARMAS:
            return 'wrong params'
        elif code == cls.RESOURCE_NOT_FOUND:
            return 'resources not found'


def wrap_json_response(data=None, code=None, message=None):
    response = {}
    if not code:
        code = ReturnCode.SUCCESS
    if not message:
        message = ReturnCode.message(code)
    if data :
        response['data'] = data
    response['result_code'] = code
    response['message'] = message
    return response


#Mixin继承
class CommnResponseMixin(object):
    @classmethod
    def wrap_json_response(cls, data=None,code=None,message=None):
        response = {}
        if not code:
            code = ReturnCode.SUCCESS
        if not message:
            message = ReturnCode.message(code)
        if data:
            response['data'] = data
        response['result_code'] = code
        response['message'] = message
        return response
response.py的代码

 

  (3)所定义的ImageView类整体代码,如下:

import os
from django.http import Http404, HttpResponse,FileResponse,JsonResponse
from git01 import settings
import utils
from django.views import View
import hashlib

from utils.response import ReturnCode


#定义类视图,主要优化以上的功能
class ImageView(View, utils.response.CommnResponseMixin):#utils.response.CommnResponseMixin是继承CommnResponseMixin类

    #这里处理get请求
    def get(self, request):
        # 接收参数
        md5 = request.GET.get("md5")

        # os.path.join的作用:1.用于路径拼接文件路径。2.还可以传入多个路径
        # 这里是结合settings设置中所配置的图片路径,在加上md5所获得数据进行拼接
        imgfile = os.path.join(settings.IMAGES_DIR, md5 + '.jpg')   #这里是进行拼接

        # 判断是否找到图片
        if not os.path.exists(imgfile):
            return Http404()
        else:
            #读取第一种方法:
            # data = open(imgfile, 'rb').read()
            # content_type代表是什么内容,简单来说就是防止乱码的出现
            # 注:解析图片这里有二种方法,具体如下:
            # 第一种方法:使用HttpResponse来解析图片
            # return HttpResponse(content=data,content_type="image/jpg")
            # 第二种方法:使用FileResponse来解析图片

            #读取第二种方法:
            return FileResponse(open(imgfile, 'rb'), content_type="image/jpg")
    def post(self, request):
        """
        实现图片上传功能
        :param request: 
        :return: 
        """
        files = request.FILES
        #遍历
        response =[]
        for key, value in files.items():
            content = value.read()
            md5 = hashlib.md5(content).hexdigest()
            path = os.path.join(settings.IMAGES_DIR, md5 + '.jpg')
            with open(path, 'wb') as f:
                f.write(content)
            response.append({
                "name": key,
                "md5": md5
            })
        message = '这是关于post方法'
        # resonse = utils.response.wrap_json_response(message=message)
        # 继承以后,直接调用CommnResponseMixin类中的wrap_json_response方法,这样的好处就是减少耦合度
        response = self.wrap_json_response(data=response, code=ReturnCode.SUCCESS,message=message)
        return JsonResponse(data=response,safe=False)

    def delete(self, request):
        """
        删除图片功能
        :param request: 
        :return: 
        """
        #获取md5数据
        md5 = request.GET.get("md5")

        #判断图片是否存在
        img_name = md5 + '.jpg'
        path = os.path.join(settings.IMAGES_DIR, img_name)
        if os.path.exists(path):
            os.remove(path)
        else:
            message = '%s文件存在' %(img_name)
        # resonse = utils.response.wrap_json_response(message=message)
        # 继承以后,直接调用CommnResponseMixin类中的wrap_json_response方法,这样的好处就是减少耦合度
        response = self.wrap_json_response(code=ReturnCode.SUCCESS, message=message)
        return JsonResponse(data=response, safe=False)

    def put(self, request):
        message = '这是关于put方法'
        # resonse = utils.response.wrap_json_response(message=message)
        #继承以后,直接调用CommnResponseMixin类中的wrap_json_response方法,这样的好处就是减少耦合度
        response = self.wrap_json_response(message=message)
        return JsonResponse(data=response, safe=False)
ImageView类完整代码

  

  (4)关于images文件所在什么地方,具体如下:

    

 

  (5)配置urls路径,首先这里定义了两个urls路径,具体如下:


    首先是本项目文件中的urls.py进行接收apis文件中的urls.py,具体配置如下:
      

 

    然后再配置pais文件中的urls.py,如下:

      

  

 2、最终效果:

  (1)url路径也配置好以后,那怎么在浏览器上进行访问?

    其实是这样访问,如下:http://127.0.0.1:8000/index/image?md5=图片名,举例:http://127.0.0.1:8000/index/image?md5=6f7aead081b3bf1dfe1734ef07d0d99d。这里的index是本项目中的urls.py设置的,image是在apis文件中的urls.py设置的,其实以上设置的名称也可以根据自己来设置。

 

    注:前提是你的images文件中有图片存在,才可以达到理想的效果。在“md5=图片名”中的这个图片名不需要加上图片的后缀名。

 

  (2)整体的效果,如下:

    

 

 二、完成小程序部分

 

  1、在pages文件下创建backup文件夹,专门来实现图片功能,backup文件夹包括js、json、wxml、wxss等这四个文件,之后再是对这些文件进行操作,具体操作如下:

  (1)先创建backup文件夹,如下:

    

   

  (2)先配置backup.wxml,如下:

<view class="page" data-weui-theme="{{theme}}">
  <view class="page__hd">
    <view class="page__title">图片备份</view>
  </view>
  <view class="page__bd">
    <view class="weui-cells">
      <view class="weui-cell">
        <view class="weui-cell__bd">
          <view class="weui-uploader">
            <view class="weui-uploader__hd">
              <view class="weui-uploader__title">上传图片</view>
              <view class="weui-uploader_info">{{files.length}}</view>
            </view>
            <view class="weui-uploader__bd">
              <view class="weui-uploader__files" id="uploaderFiles">
                <block wx:for="{{needUploadFiles}}" wx:key="*this">
                  <view class="weui-uploader__file" data-type="UploadView" bind:longpress="longTapConfirm" data-id="{{item}}">
                    <image class="weui-uploader__img" src="{{item}}" mode="aspectFill" />
                  </view>
                </block>
              </view>
              <view class="weui-uploader__input-box">
                <view class="weui-uploader__input" bindtap="chooseImage"></view>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>
    <view class="page__bd page__bd_spacing button-sp-area">
      <button class="weui-btn" type="primary" bindtap='uploadFiles'>确认上传</button>
      <button class="weui-btn" type="primary" bindtap='downloadFile'>下载图片</button>
      <button class="weui-btn" type="primary" bindtap='deleteBackup'>删除图片</button>
    </view>



    <!-- 已上传图片 -->
    <view class="weui-cells">
      <view class="text-center">已备份图片</view>
      <view class="weui-cell" wx:for="{{downloadedBackupedFiles}}">
        <image class="" src="{{item}}" mode="aspectFill" data-index="{{index}}" data-type="DownloadedView" bindlongtap="longTapConfirm" />
      </view>
    </view>
    <view class='text-center' wx:if="{{downloadedBackupedFiles.length == 0}}">暂无</view>
  </view>
</view>
backup整体代码

 

   (3)再配置backup.js,具体如下:

const app = getApp()
const imageUrl = app.globalData.serverUrl + app.globalData.apiVersion //这里可以理解为路径拼接

Page({
  data: {
    // 需要上传的图片
    needUploadFiles: [],
    // 已下载的备份图片
    downloadedBackupedFiles: [],
  },

  // 选择图片上传
  chooseImage: function(e) {
    var that = this;
    wx.chooseImage({
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function(res) {
        // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
        that.setData({
          needUploadFiles: that.data.needUploadFiles.concat(res.tempFilePaths)
        });
      }
    })
  },

  // 上传图片文件
  uploadFiles: function() {
    for(var i=0;i<this.data.needUploadFiles.length;i++){
      var filePath= this.data.needUploadFiles[i]
      wx.uploadFile({
        filePath: filePath,
        name: 'test',
        url: imageUrl,
        success: function(res){
          //打印结果
          console.log(res)
        }
      })
    }
  }
});
backup.js整体代码

 

  2、在该文件中具体配置app.js、app.json、app.wxss,具体操作如下:

  (1)先配置app.js,具体如下:

//app.js
App({
  onLaunch: function () {
    // 展示本地存储能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
    })
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  onShow: function(){},
  onHide: function(){},
  globalData: {
    userInfo: null,
    serverUrl: 'http://127.0.0.1:8000',
    apiVersion: '/index/image'
  }
})
app.js整体代码

   注:①app.js中的serverUrl必须要跟Django的url路径一致。在以上的代码中的url是127.0.0.0:8000,而Django中的url也是127.0.0.0:8000,举例:如果我只该小程序的路径,改为127.0.0.0:8001,再运行小程序时,会发现出现“uploadFile:fail Error: connect ECONNREFUSED 127.0.0.1:8001”的问题,所以小程序中的路径和Django的路径必须要一致。 ②apiVersion就是根据Django中的urls来设置,所以也需要一致。 

     

   (2)接下来继续配置app.json,由于创建backup文件夹,所以需要在pages集合中定义,具体如下:

   

 

   (3)在底部导航栏添加相关图片的子网页,主要用来实现图片功能,具体配置如下(还是在app.json文件下配置):

   

 

   (4)再看看底部导航栏是否有“图片”存在,效果如下:
   

 

  (5)以下就是关于app.json整体代码:

{
  "pages": [
    "pages/index/index",
    "pages/userConsole/userConsole",
    "pages/storageConsole/storageConsole",
    "pages/databaseGuide/databaseGuide",
    "pages/addFunction/addFunction",
    "pages/deployFunctions/deployFunctions",
    "pages/chooseLib/chooseLib",
    "pages/openapi/openapi",
    "pages/openapi/serverapi/serverapi",
    "pages/openapi/callback/callback",
    "pages/openapi/cloudid/cloudid",
    "pages/im/im",
    "pages/logs/logs",
    "pages/im/room/room",
    "pages/menu/menu",
    "pages/backup/backup"
  ],
  "window": {
    "backgroundColor": "#F6F6F6",
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#F6F6F6",
    "navigationBarTitleText": "云开发 QuickStart",
    "navigationBarTextStyle": "black"
  },
  "tabBar": {
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页"
       
      },
      {
        "pagePath": "pages/logs/logs",
        "text": "日志"
      },
      {
        "pagePath": "pages/menu/menu",
        "text": "应用"
      },
      {
        "pagePath": "pages/backup/backup",
        "text": "图片"
      }
    ]
  },
  "sitemapLocation": "sitemap.json",
  "style": "v2"
}
app.json代码

 

   (6)优化自己的app.wxss代码:

 page {
  line-height: 1.6;
  font-family: -apple-system-font, Helvetica Neue, sans-serif
}

icon {
  vertical-align: middle
}

.weui-cells {
  position: relative;
  margin-top: 1.17647059em;
  background-color: #fff;
  line-height: 1.41176471;
  font-size: 17px
}

.weui-cells:before {
  top: 0;
  border-top: 1rpx solid #d9d9d9
}

.weui-cells:after,
.weui-cells:before {
  content: " ";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  color: #d9d9d9
}

.weui-cells:after {
  bottom: 0;
  border-bottom: 1rpx solid #d9d9d9
}

.weui-cells__title {
  margin-top: .77em;
  margin-bottom: .3em;
  padding-left: 15px;
  padding-right: 15px;
  color: #999;
  font-size: 14px
}

.weui-cells_after-title {
  margin-top: 0
}

.weui-cells__tips {
  margin-top: .3em;
  color: #999;
  padding-left: 15px;
  padding-right: 15px;
  font-size: 14px
}

.weui-cell {
  padding: 10px 15px;
  position: relative;
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
  align-items: center
}

.weui-cell:before {
  content: " ";
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  height: 1px;
  border-top: 1rpx solid #d9d9d9;
  color: #d9d9d9;
  left: 15px
}

.weui-cell:first-child:before {
  display: none
}

.weui-cell_active {
  background-color: #ececec
}

.weui-cell_primary {
  -webkit-box-align: start;
  -webkit-align-items: flex-start;
  align-items: flex-start
}

.weui-cell__bd {
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  flex: 1
}

.weui-cell__ft {
  text-align: right;
  color: #999
}

.weui-cell_access {
  color: inherit
}

.weui-cell__ft_in-access {
  padding-right: 13px;
  position: relative
}

.weui-cell__ft_in-access:after {
  content: " ";
  display: inline-block;
  height: 6px;
  width: 6px;
  border-width: 2px 2px 0 0;
  border-color: #c8c8cd;
  border-style: solid;
  -webkit-transform: matrix(.71, .71, -.71, .71, 0, 0);
  transform: matrix(.71, .71, -.71, .71, 0, 0);
  position: relative;
  top: -2px;
  position: absolute;
  top: 50%;
  margin-top: -4px;
  right: 2px
}

.weui-cell_link {
  color: #586c94;
  font-size: 14px
}

.weui-cell_link:active {
  background-color: #ececec
}

.weui-cell_link:first-child:before {
  display: block
}

.weui-icon-radio {
  margin-left: 3.2px;
  margin-right: 3.2px
}

.weui-icon-checkbox_circle,
.weui-icon-checkbox_success { 
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap