美文网首页
【微信小程序+Django REST framework】无图或

【微信小程序+Django REST framework】无图或

作者: 焜_8899 | 来源:发表于2020-02-09 21:04 被阅读0次

    1. 说明

    使用前后端分离的模式。
    前端:微信小程序(以下简称“小程序”)
    后端:Django REST framework

    2. 前端部分

    2.1 wxss

    使用微信原生样式WeUI。使用方法详见这里

    2.2 wxml

    2.2.1 <form>组件

    将组件内的用户输入的switch input checkbox slider radio picker 提交。

    当点击 form 表单中 form-type 为 submit 的 button 组件时,会将表单组件中的 value 值进行提交,需要在表单组件中加上 name 来作为 key。

    使用radio时,name应当加在radio-group

    2.2.2 <button>组件

    就是按钮。

    2.2.3 示例代码

    wxml
    <form bindsubmit="formSubmit">
        <view class="weui-form__opr-area"> <!--此处class表示使用了相应的weui样式-->
          <button formType="submit" type="primary">确定</button>
        </view>
    </form>
    
    JavaScript
    Page({
      formSubmit: function (e) {
        console.log('form发生了submit事件,携带数据为:', e.detail.value)
      },
    })
    

    2.3 js

    2.3.1 wx.request() API

    小程序提供了wx.request() API用于发起https请求

    • 需要在method属性中填入GET或POST等等以发起相应请求
    • 数据格式默认为json,会自动对数据进行 JSON 序列化,可改
    • 不包含文件

    官方示例代码

    wx.request({
      url: 'test.php', //仅为示例,并非真实的接口地址
      data: {
        x: '',
        y: ''
      },
      header: {
        'content-type': 'application/json' // 默认值
      },
      success (res) {
        console.log(res.data)
      }
    })
    

    2.3.2 wx.uploadFile() API

    小程序还提供了wx.uploadFile() API用于将本地资源上传到服务器

    • 会发起一个https POST请求
    • 每次都必须且仅能上传一个文件
    • 可在上传文件的同时携带表单数据

    官方示例代码

    wx.uploadFile({
      url: 'https://example.weixin.qq.com/upload', //仅为示例,非真实的接口地址
      filePath: tempFilePaths[0],
      name: 'file',
      formData: {
        'user': 'test'
      },
      success (res){
        const data = res.data
        //do something
      }
    })
    

    2.3.3 示例代码

    使用wx.request()时无法上传文件,而使用wx.uploadFile()时必须包含一个文件,但实际表单里用户可以选择添加或不添加图片。于是,需要判断是否有图片,并分别调用相应的方法。

    结合上述wxml部分提交表单相应代码,最终js代码如下:

    pageName.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        files: [],
      },
    
      /* “确定”按钮被点击 */
      formSubmit: function (e) {
        console.log('form发生了submit事件,携带数据为:', e.detail.value);
    
        var formData = e.detail.value; //提取表单数据
        
        if (this.canSubmit(formData)) //判断是否满足提交条件,比如用户输入的数据是否有误
        {
          /*向服务器发送数据,有图和无图时调用的方法不同*/
          if (this.data.files[0]) {
            /*若有图*/
            wx.uploadFile({
              url: 'http://127.0.0.1:8000/app/api/', //服务器API
              filePath: this.data.files[0],
              name: 'image',
              formData: formData, //表单数据
            })
          }
          else {
            /*若无图*/
            wx.request({
              url: 'http://127.0.0.1:8000/app/api/', //服务器API
              data: formData, //表单数据
              method: 'POST',
            })
          }
        }
        else {
          console.log('不能提交')
        }
      },
    })
    

    2.4 补充说明

    在小程序中使用网络相关的 API 时,有诸多问题需要注意
    在开发时可做如下设置:

    详情 - 本地设置 - 不校验合法域名.png

    3. 后端部分

    本人实际操作前学习了孙振强的《Django REST framework 初体验》,获益匪浅。

    3.1 新建应用

    python manage.py startapp appName
    

    把新应用移动到项目根目录的apps文件夹下。如果没有的话,就新建一个。当应用多了之后,放在一个文件夹里会有便于管理。

    3.2 注册应用

    每当新建了应用之后,不要忘了在settings.py里注册新应用。

    settings.py
    INSTALLED_APPS = [
        ...
        'rest_framework',
        'apps.appName'
    ]
    

    3.3 编写模型

    apps\appName\model.py
    from django.db import models
    
    class ClassName(models.Model):
        image = models.ImageField(upload_to="images/%Y/%m/", null=True, blank=True)
    

    upload_to里填的是后端接收到文件之后的保存路径,上传文件之后会自动创建。
    %Y表示年份,%m表示月份,便于分类管理。

    注意:使用ImageField需要先安装Pillow

    pip install Pillow
    

    3.4 配置数据库

    每当新建或修改了model.py之后,不要忘了做数据迁移。

    python manage.py makemigratons appName
    python manage.py migrate appName
    

    如果不想用django自带的数据库,可在settings.py中修改。

    3.5 修改设置

    settings.py里添加以下内容,设置静态文件路径为项目根目录下的media文件夹。

    settings.py
    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    

    3.6 编写序列化模块

    apps\appName\下新建文件serializers.py

    apps\appName\serializers.py
    from rest_framework import serializers
    
    from .models import ClassName
    
    
    class ClassNameSerializer(serializers.ModelSerializer):
        class Meta:
            model = ClassName
            fields = '__all__' # 默认生成所有字段
    
    

    3.7 编写视图

    apps\appName\views.py
    from rest_framework import status
    from rest_framework.response import Response
    from rest_framework.views import APIView
    
    from .models import ClassName
    from .serializers import ClassNameSerializer
    
    
    class ClassNameView(APIView):
        def get(self, request, format=None):
            class_name = ClassName.objects.all()
            serializer = ClassNameSerializer(class_name, many=True)
            return Response(serializer.data)
    
        def post(self, request, format=None):
            serializer = ClassNameSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    

    3.8 编写路由

    3.8.1 应用路由

    apps\appName\urls.py(没有的话就新建一个)
    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        url(r'^api/$', views.ClassNameView.as_view())
    ]
    
    

    3.8.2 项目路由

    项目根目录\urls.py(这个不可能没有)
    from django.contrib import admin
    from django.urls import path
    from django.conf import settings
    from django.conf.urls import url, include
    from django.conf.urls.static import static
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        url(r'^api-auth/', include('rest_framework.urls')),
        url(r'^app/', include('apps.appName.urls'))
    ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    
    

    4. 参考文献

    本文所有参考文献均已以链接的形式标注在了对应位置。

    相关文章

      网友评论

          本文标题:【微信小程序+Django REST framework】无图或

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