本人小白一枚,最近想完成一个小程序界面,把上传的图片和表单一起传入后台,研究了一阵,现在把自己的体会分享一下,也当做笔记了。

1:wx.chooseMedia存入图片临时路径

首先,我们要把上传的图片路径存入wx.chooseMedia里(之前是wx.chooseImage,从基础库2.21.0开始,该接口停止维护,使用wx.chooseMedia代替)

参考链接:wx.chooseMedia(Object object) | 微信开放文档

下面展示我的页面:

wxml界面:这里定义了两个事件,uploadImg用于上传图片(就是把我们相册或者拍照的图片上传到界面上)然后存入到临时路径到时候和表单通过submit事件一起提交。

js界面:下面我们就要来完成具体事件的功能,完成uploadImg事件后上传的图片应该会显示在界面上显示出来可供我们浏览了。完成submit事件提交图片和表单。

uploadImg事件

2.wx.uploadFile上传图片和表单

参考链接:UploadTask | 微信开放文档

submit事件

这里我上网查看资料,有人说先用uploadFile把图片临时存放起来,然后用wx.request发起请求把表单和图片通过data属性提交。我试了一下,发现把图片上传后是字符串类型,因为data属性默认类型是string。后台能接受到这个参数,但是得不到具体数据内容。这使表单数据能存入数据库,但图片实体存入不了,只能存入字符串。而uploadFile能存入图片

数据库显示:

这里通过wx.request上传可能是我还没有悟到(应该是data属性格式转换有问题,或者是我django数据库字段类型定义有误,再或者是后台取数据有误,不能使图片存入数据库),使用request和uploadFile有几个地方有坑需要注意一下:

参考1:https://www.cnblogs.com/huangshuqiang/p/9907598.html

参考2:https://www.cnblogs.com/bosins/p/14783932.html

3.后端diango配置

因为我主要是想记录小程序内容,所以django就略过一下,还是会把所有代码和设计流程写下(详细就不说啦,自己也不是很会,怕误导家人们!!!)

首先要创建django项目、创建app文件、在settings.py中INSTALLED_APPS下写入创建的app文件名、配置图片存放路径、配置MySQL数据库、写视图文件、配置url地址。上面的基础搭建信息可以去找django大神的博客看。这里我就从配置图片存放路径开始噢。

在settings.py文件最下面配置图片存放路经:

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')    # 设置文件夹名
MEDIA_URL = '/media/'                           # url映射

在自己创建的app文件下的models.py文件中定义数据库字段(upload_to意思是把图片存入media文件夹下的photo文件夹下):

from django.db import models

class Company(models.Model):
    picture = models.ImageField(upload_to='photo', verbose_name='公司资质')
    title = models.CharField(max_length=50)
    number = models.CharField(max_length=50)
    time = models.DateTimeField(auto_now_add=True, editable=False)

django连接MySQL数据库还要在__init__.py下定义,这样数据库才能连接成功。:

import pymysql
pymysql.install_as_MySQLdb()

上面定义好后,就可以生成迁移文件(makemigrations)和数据迁移(migrate)了。迁移好之后就和mysql数据库连接好了:

django采用ORM(对象关系映射),也就是类对应MySQL的表,属性对应MySQL的字段。然后QuerySet(查询集)通过各种接口和字段使ORM达到跟SQL语句同样的表单能力!

接下来就编写views.py视图文件了:

from django.shortcuts import render
from .models import Company
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse 
from . import models

from rest_framework.views import APIView
from rest_framework.response import Response


# 把数据转换成json格式
def json_company(request):
    ret = Company.objects.all().order_by('-id')[:1]
    json_list = []
    for i in ret:
        json_list.append({"id":i.id, "picture":str(i.picture), "title":i.title, "number":i.number, "time":i.time})
    return JsonResponse(json_list, safe=False)

# 获得小程序数据,并存入数据库
class companyView(APIView):
    def post(self, request, *args, **kwargs):
        print(request.data)
        data = models.Company(
            picture = request.FILES.get('file'),
            title = request.POST.get('title'),
            number = request.POST.get('number'),
        )
        data.save()
        return Response({'status': True})

小程序要获得数据库的数据就要转换成json格式通过接口传给它,json_company就是把数据转化为json格式。我这里后台接收小程序上传的数据使用了Django Rest_Framework框架。

参考链接1:https://blog.csdn.net/qq_45261963/article/details/123981719

参考链接2:django获取微信小程序的数据_微信小程序 得不到django后台数据-CSDN博客

1)安装djangorestframework:

下载慢的话可以用镜像源来加速。有时候安装第三方包出现错误时考虑是网速的原因,这时采用国内的镜像源来加速:
pip install 包名-i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
# 清华镜像
pip install 包名-i https://pypi.tuna.tsinghua.edu.cn/simple

pip install djangorestframework

 2)定义app文件夹下urls.py的url地址:

 3)定义项目文件夹下urls.py的url地址:

上面的完成好之后我们后端的接口差不多就完成好了,现在只要把API接口放入wx.uploadFile的url属性里就可以实现微信小程序+django+MySQL数据交互了。就相当于小程序是前端,django是后端,django实现小程序上传数据的增删改查存入MySQL数据库

4.完整代码!

wxml:

<view class="top-box">公司资质</view>

  <view class="company">
    <view bindtap="uploadImg" class="btn">---选择图片---</view>
    <view class="imgs">
      <image wx:if="{{imgList}}" src="{{imgList}}" class="imgList" mode="widthFix"></image>
      <!-- <image src="{{ imgUrl }}" class="imgList"></image> -->
    </view>
  </view>
<form class="formBox" bindsubmit="submit">
  <text>文件标题:</text><input name="title" placeholder="请输入文件标题" bindinput="companyTitle"/>
  <text>资格证号:</text><input name="number" placeholder="请输入资格证号" bindinput="companyNumber"/>
  <view class="center">
    <button form-type="reset" type="warn"class="butt2">取消</button>
    <button form-type="submit" type="primary" class="butt1">提交</button>
  </view>
</form>

wxss:(css不怎么会,乱搞的。。有大神能指教我一下不)

.top-box {
  height: 80rpx;
  background-color: lightskyblue;
  line-height: 80rpx;
  text-align: center;

}
.formBox {
  width: auto;
  height: auto;
  display: inline;
  
}
.formBox text{
  margin-left: 10rpx;
  margin-top: 10rpx;
  display: block;
}

.formBox input {
  border: 1rpx solid #79aec8;
  width: 60%;
  margin-top:10rpx;
  margin-left: 10rpx;
  display: block;
  padding-left: 10rpx;
}

.formBox textarea {
  border: 1rpx solid #79aec8;
  width: 60%;
  margin-left: 10rpx;
  margin-top: 10rpx;
  display: block;
  padding-left: 10rpx;
}
.center {
  position: absolute;
  margin-top:20rpx;
}

.center button{
  padding: 10rpx;
  width: 150rpx;
  display: inline;
  margin-left: 200rpx;
}
.company {
  border: 1rpx dotted #807d7d;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
}

.btn {
	padding: 15rpx 20rpx;
	color: rgb(5, 0, 0);

}
.imgs image{
  width: 200rpx;
  height: 200rpx;
}

.imgList {
  width: 200rpx;
  height: 200rpx;
}

js:

Page({

  /**
   * 页面的初始数据
   */
  data: {
    title: "",
    number: "",
    // 存放微信图片地址
    imgList: "",
  },
  // 文件标题
  companyTitle: function(e) {
    // console.log(e)
    this.setData({ title: e.detail.value })   // 获取从键盘输入的值
  },
  // 资格证号
  companyNumber: function(e) {
    this.setData({ number: e.detail.value })
  },
  
  /* 选择文件,得到临时路径 */
	uploadImg: function () {
    var that = this;
    // chooseImage已停止维护,需使用chooseMedia选择上传
    // 选取图片
		wx.chooseMedia({
			count: 1, // 选择的图片个数,默认值9
			mediaType: ['image'], // 文件类型
			sizeType: ['original'], // 是否压缩所选文件
			sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
			success: res => {
				// console.log(res);
				that.setData({
					imgList: res.tempFiles[0].tempFilePath
        })
        // console.log(that.data.imgList);
        console.log(res);
        // console.log("img-url:", res.tempFiles[0].tempFilePath)
        wx.showToast({
          title: '已选择图片',
          icon: 'none'
        })
      },
      fail: res => {
        wx.showToast({
          title: '未选择图片',
          icon: 'none'
        })
      }
    })
  },

  // 提交
  submit() {
    var alreadyChoosedImageList = this.data.imgList;
    var title = this.data.title
    var number = this.data.number
    // 上传图片
    wx.uploadFile({
      filePath: alreadyChoosedImageList,   //要上传文件资源的路径 (本地路径)
      name: 'file',
      url: 'xxx/xxx/companyView/',        // 自己的API接口
      header: {
        "content-type": "multipart/form-data",
      },
      formData: {
        // title: "你好",
        // number: "18"
        title: JSON.stringify(title),
        number: JSON.stringify(number)
      },
      success: res => {
        console.log('上传成功:', res)
        wx.showToast({
          title: '图片上传成功',
          icon: 'success'
        });
      },
      fail: function (err) {
        console.error(err);
        wx.showToast({
          title: '图片上传失败',
          icon: 'none'
        });
      }
    })
  },
}) 

运行结果图:

结语:小程序上传图片和表单至后台大概就是这样,如果有接口的话就不用配置第3部分了,直接在uploadFile的url里面用就行。本人刚接触码农不久,如有错误请别恶语相向和冷嘲热讽(本人玻璃心),初衷也记录一下就当做笔记了。有学python小伙伴可以加个联系方式一起学习和探讨!

环境:python:3.3.0        django:2.2.8        

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐