前言

不知不觉已经九月了,又到了一年的开学季,我每年都想做的项目墙甚至连个影子都没有…

最近生活中的琐事太多了,导致完全没有想写文章的动力,不过再怎么拖还是得记录,随便写写吧~

这次是7月份的一个小项目,谈不上什么技术含量,算是友情开发了。后端 DjangoStarter v3,前端使用 Taro 做微信小程序。

事实上后端基本没啥好说的,基本有什么坑能记录的都在小程序这块,不得不说微信真是史中史,不仅代码写得跟答辩一样,文档更是一坨

之前看网上有个说法,正因为微信做得跟答辩一样,才给了小程序开发者一道护城河,现在想起来还蛮有道理的,哈哈哈

后端部分

先来说说后端部分吧

自从有了 DjangoStarter ,这类小项目的后端开发已经直接秒了

这个项目里用到几个新的,我之前有写文章介绍了,直接放链接吧~

使用 django-filer 管理文件

忘了这个还没写文章,那么简单介绍一下吧,这个组件可以实现文件(包括图片)的集中管理,还提供了 admin 界面,不过UI风格就比较原始了,而且中文locale还有bug,得手动修改才能正常切换到中文。不过对于这个项目来说是够用的

项目地址: https://github.com/django-cms/django-filer

安装: pdm add django-filer

filer 添加到 INSTALLED_APPS

添加 src/config/settings/components/filer.py 配置

THUMBNAIL_PROCESSORS = (
'easy_thumbnails.processors.colorspace',
'easy_thumbnails.processors.autocrop',
'easy_thumbnails.processors.scale_and_crop',
# Subject location aware cropping
# 'filer.thumbnail_processors.scale_and_crop_with_subject_location',
'easy_thumbnails.processors.filters',
) FILER_ENABLE_LOGGING = True

最后修改一下需要用到附件的字段

from filer.fields.image import FilerImageField

class Brand(ModelExt):
name = models.CharField('名称', max_length=100)
# logo = models.ImageField(upload_to='brand_logos/')
logo = FilerImageField(
verbose_name='Logo', null=True, blank=True,
related_name='+', on_delete=models.SET_NULL,
)

大概就这样,具体用法看官方文档吧~

使用 ninja 来编写API

DjangoStarter v3 开始从drf 切换到 ninja

这个 ninja 和 FastAPI 非常像,写起来比 drf 舒服多了,虽然不能像 drf 一样自动生成 crud 接口,不过写起来也多不了多少代码,而且更加灵活。

(PS:DjangoStarter v3 依然支持自动生成 crud 接口,同时还可以使用第三方库来实现自动生成基于 ninja 的 crud 接口,不过我还没用过,可以参考下面的扩展部分)

比如上面说的 django-filer 库,图片字段其实是指向 filer.fields.models.File 模型的外键,所以接口如果没做处理,生成出来的数据就只是一个外键ID而已,所以要修改一下 schema

class CaseOut(ModelSchema):
cover_image: str @staticmethod
def resolve_cover_image(obj: Case):
if not obj.cover_image:
return f'https://starblog/Api/PicLib/Random/{obj.id}/250/150'
return obj.cover_image.url class Meta:
model = Case
fields = [
'id', 'is_deleted', 'created_time', 'updated_time', 'name', 'description',
'category', 'car_model', 'part', 'build_time',
]

以上代码会把 cover_image 字段渲染为一个图片地址,如果 cover_image 不存在的话,则返回一个随机图片地址。

schema 实现了逻辑和数据渲染分开,代码结构更清晰。

还可以实现更复杂的逻辑,只需要实现 resolve_字段名 方法就行。

ninja 生态扩展

我也是最近才发现的,原来 django-ninja 还有个中文网,里面写了几个 ninja 生态的扩展,感觉都挺不错的,以后有空可以试试。

网址: https://django-ninja.cn/

  • Ninja JWT - 一个用于 Django Ninja REST 框架的 JSON Web 令牌认证插件。
  • Django Ninja Extra - Django Ninja Extra 提供了一种 基于类 的方法以及额外的功能,这将使用 Django Ninja 加速您的 RESTful API 开发。
  • Django Ninja CRUD - Django Ninja CRUD 是一个强大的、声明式的、但又有点固执己见的框架,它简化了使用 Django Ninja 开发 CRUD(创建、读取、更新、删除)端点的过程,并且还提供了一种声明式的基于场景的方法,用于使用 Django REST Testing(这个包的小弟)测试这些端点。

小程序部分

这次依然使用 Taro 来开发移动端,上次是做 H5(公众号),这次试试 Taro 做出来的小程序咋样,实际效果还行。

状态管理依然选择了 mobx ,用习惯了,前端轮子太多,懒得去试用其他的了~

相比起后端部分,小程序能写的东西会多一点点(但也不多,都很简单)

在Taro里使用tailwindcss

最近我开始使用 tailwindcss ,一下就喜欢上这种高效的样式工具(虽然会有很长的一串class)不过瑕不掩瑜,使用 tailwindcss 可以很方便在网络上 copy 各种样式,还能让 LLM 帮我写各种样式,生产力拉满了~

Taro 官方提供了 tailwindcss 的支持,这点非常好,跟着官方文档来就行

详见官方文档: https://docs.taro.zone/docs/tailwindcss

分享小程序

如果不主动调用,那么只有注册了 onShareAppMessage 事件,才能在点右上角三个点的时候,显示转发按钮;同样的,注册了 onShareTimeline 事件才能分享到朋友圈。

相应的,Taro 里提供了这俩事件的 hook ,直接看代码

import Taro, {useShareAppMessage, useShareTimeline} from '@tarojs/taro'

const CasePage = () => {
const getCase = async () => {
if (!id) return
const data = await CaseService.get(Number(id))
console.log('get case', data)
setCaseData(data.data)
return {
title: `案例:${data.data.name}`,
path: RouterMap.car.case(data.data.id),
imageUrl: data.data.cover_image
}
} useShareAppMessage(res => {
console.log('执行分享操作', res)
return {
title: '案例分享',
path: RouterMap.index,
promise: new Promise(resolve => getCase().then((data) => {
// @ts-ignore
resolve(data)
})),
}
}) useShareTimeline(() => {
console.log('执行分享朋友圈操作') return {
title: `案例:${caseData.name}`,
query: `id=${caseData.id}`,
imageUrl: caseData.cover_image
}
})
}

跟小程序文档里说的一样的,需要返回的参数啥的也一样,所以直接看文档吧~

主动分享

主动分享的话,只要把按钮设置成 share 类型就行,Taro 同样做了包装。

<Button type='info' icon={<Share/>} openType='share'>分享</Button>

参考资料

用户登录

本项目中我是做一个单独的页面来处理登录,也可以用 Modal 的形式,不过一开始我还对获取用户信息抱有幻想,因为文档介绍获取用户头像、昵称等信息需要主动触发才行,所以放在一个单独的页面,提供一个登录按钮,让用户去点击。

不过后面发现新版本的小程序已经不能用这种方式获取信息了……

登录这块 Taro 也封装好了,其实就是把 wx.login 的 wx 改成 Taro 而已

const LoginPage = observer(() => {
const handleLogin = async (data: LoginToken) => {
UserStore.login({
token: data.token,
exp: String(data.exp),
}) const userInfo = await AccountService.getCurrentUser()
console.log('获取用户信息', userInfo)
UserStore.userInfo = userInfo.data
Taro.navigateBack()
} const autoLogin = async () => {
Taro.showToast({title: '正在登录', icon: 'loading'})
Taro.login({
success: async (res) => {
if (res.code) {
console.log('小程序登录,获取code', res.code)
const resp = await AccountService.loginWeApp(res.code)
console.log('小程序登录,请求后端', resp)
await handleLogin(resp.data)
} else {
console.log('登录失败!', res.errMsg)
}
}
})
}
}

拿到小程序 OAuth 之后的 code,调用后端接口登录,搞定。

而且这部分 DjangoStarter v3 也集成了

点击图片打开大图

在图片组件的 onTap 事件里调用 Taro.previewImage 就行,记得把大图的地址传入(如果小图是单独的地址的话)

<Image
key={e.id} src={e.url}
onTap={() => {
Taro.previewImage({
current: e.url,
urls: caseData.images.map(i => i.url)
})
}}
className="w-full rounded shadow"
mode="aspectFill"
/>

部署

这次的部署也是船新版本

这个项目也算是新版 DjangoStarter 的第一次实践,所以遇到一些坑,我都写了博客记录了

总得来说 daphne 服务器用着还不错。

小结

开头就说了,本次项目的算是比较简单的,时间主要花在前端的交互和一些细节的调整上

Taro 用来开发小程序还是丝滑的,意料中打包和发布可能遇到的问题,实际上都没有

这篇小结真的拖了太久了,我也好久没写代码了… 得抓紧时间整理思绪,然后把想做的东西都搞起来了。

项目完成小结:使用DjangoStarter v3和Taro开发的微信小程序的更多相关文章

  1. 开发一个微信小程序教程

    一.注册小程序账号 1.进入微信公众平台(https://mp.weixin.qq.com/),注册小程序账号,根据提示填写对应的信息即可. 2.注册成功后进入首页,在 小程序发布流程->小程序 ...

  2. 开发一个微信小程序项目教程

    一.注册小程序账号 1.进入微信公众平台(https://mp.weixin.qq.com/),注册小程序账号,根据提示填写对应的信息即可.2.注册成功后进入首页,在 小程序发布流程->小程序开 ...

  3. 如何快速地开发一个微信小程序

    如何快速地开发一个微信小程序呢?我觉得作为初学者,最好能有一个模板,然后改这个模板. 同样作为初学者,刚开始的时候我有下面的几个问题,后来通过问同学,我弄清楚了. 微信小程序可以连接MySQL或者Sq ...

  4. 全栈开发工程师微信小程序-中(下)

    全栈开发工程师微信小程序-中(下) 微信小程序视图层 wxml用于描述页面的结构,wxss用于描述页面的样式,组件用于视图的基本组成单元. // 绑定数据 index.wxml <view> ...

  5. 全栈开发工程师微信小程序-中(中)

    全栈开发工程师微信小程序-中(中) 开放能力 open-data 用于展示微信开放的数据 type 开放数据类型 open-gid 当 type="groupName" 时生效, ...

  6. 全栈开发工程师微信小程序-中

    全栈开发工程师微信小程序-中 多媒体及其他的组件 navigator 页面链接 target 在哪个目标上发生跳转,默认当前小程序,可选值self/miniProgram url 当前小程序内的跳转链 ...

  7. 全栈开发工程师微信小程序-上(下)

    全栈开发工程师微信小程序-上(下) icon 图标 success, success_no_circle, info, warn, waiting, cancel, download, search, ...

  8. 全栈开发工程师微信小程序-上(中)

    全栈开发工程师微信小程序-上(中) width: 750rpx; 750rpx代表与屏幕等宽,rpx的缩写responsive pixel,这个单位是可以根据屏幕大小进行自适应调整的像素单位. 小程序 ...

  9. 全栈开发工程师微信小程序 - 上

    全栈开发工程师微信小程序-上 实现swiper组件 swiper 滑块视图容器. indicator-dots 是否显示面板指示点 false indicator-color 指示点颜色 indica ...

  10. 开发一个微信小程序实例教程

    一.注册小程序账号 1.进入微信公众平台(https://mp.weixin.qq.com/),注册小程序账号,根据提示填写对应的信息即可.2.注册成功后进入首页,在 小程序发布流程->小程序开 ...

随机推荐

  1. 转载 | win11右键菜单改为win10的bat命令(以及恢复方法bat)

    原文来自这里:https://blog.51cto.com/knifeedge/5340751 版权归:IT利刃出鞘 本质上就是写入注册表. 一.右键菜单改回Win10(展开) 1. 新建文件:win ...

  2. 推荐2款.NET开源、轻便、实用的Windows桌面启动器

    Flow Launcher Flow Launcher是一款.NET开源(MIT License).免费.功能强大.方便实用的 Windows 文件搜索和应用程序启动器,能够帮助你快速查找文件.启动应 ...

  3. Memcache 与 Memcached 的区别

    Memcached 从0.2.0开始,要求PHP版本>=5.2.0,Memcache 要求PHP版本>=4.3. Memcached 最后发布时间为2018-12-24,Memcache ...

  4. 判断C盘下有没有Templets文件夹,没有则新建,然后判断Templets文件夹下有没有TEST.xlt文件

    VB.NET 判断C盘下有没有Templets文件夹,没有则新建,然后判断Templets文件夹下有没有TEST.xlt文件,如果没有则新建   你可以使用VB.NET中的Directory和File ...

  5. [oeasy]python0037_字符画艺术_asciiview_自制小动物_imagick_asciiart

    ​ 牛说(cowsay) 回忆上次内容 我们狂飙了一路 从用shell 直接执行 python程序 到用shell 循环执行 python程序 循环体中 把 python的 输出结果 用管道 交给了 ...

  6. EasyDesktop 浏览器书签管理从未如此简单

    作为一名软件开发从业人员, 每天80%的时间都在与浏览器打交道, 一半的时间在用浏览器开发调试, 另一半时间则是在互联网上搜寻各种知识和资源. 为此, 我的浏览器书签栏存储和很多非常棒的链接, 多到2 ...

  7. Day 3 - 单调栈、单调队列、凸包与斜率优化

    单调栈 引入 何为单调栈?顾名思义,单调栈即满足单调性的栈结构.与单调队列相比,其只在一端进行进出. 为了描述方便,以下举例及伪代码以维护一个整数的单调递增栈为例. 过程 插入 将一个元素插入单调栈时 ...

  8. vue小知识~eventBus

    eventBus是指在向全区暴露这个vue对象,此时在任意一个地方都可以使用vue相关的实例 在main.js配置 Vue.prototype.$bus=new Vue() 此时整个应用都可以使用vu ...

  9. 【微信小程序】 分包

    1. 什么是分包 分包指的是把一-个完整的小程序项目,按照需求划分为不同的子包, 在构建时打包成不同的分包,用户在使用时按需进行加载. 2. 分包的好处 对小程序进行分包的好处主要有以下两点: ● 可 ...

  10. 【Mybatis】Bonus01 笔记资料

    对原生JDBC程序的问题总结 public void jdbc() { // 声明Connection对象 Connection con; // 驱动程序名 String driver = " ...