Django WeChat Extension
Project description
WeChat-Django
WeChat-Django旨在为接入微信公众平台的django开发者提供便捷的微信及微信支付功能封装及基本的后台管理支持.
项目官方地址: https://github.com/Xavier-Lam/wechat-django
本拓展基于wechatpy ,支持的最低django版本为1.11. WeChat-Django只是一个预览版本,可能存在较多bug并且有api及数据结构变更可能.
目录
功能
- 公众号管理
- 同步用户及用户查看,备注,用户标签管理
- 菜单同步,查看及发布
- 同步公众号自动回复,管理自动回复,转发和自定义自动回复业务,接收消息日志
- 模板消息模板的同步及发送
- 永久素材,图文的同步及查看
- 微信网页授权
- 主动调用微信api封装
- 微信支付api封装
- 微信支付订单管理及信号
- 后台权限管理
- django-rest-framework APIView兼容
- 迁移公众号自动回复/菜单/素材(不建议)
安装及配置
初次安装
- 运行pip install wechat-django[cryptography] 或 pip install wechat-django[pycrypto] 安装
- 在settings.py的INSTALLED_APPS中添加wechat_django
- 运行manage.py migrate wechat_django 来更新数据库结构
- 在urls.py 中引入wechat_django.sites.wechat.urls, 将其配置到urlpatterns中
至此,您已可以开始轻松使用wechat_django.项目尚未提供具体的使用文档,如需客制化需求,烦请先阅读代码
直接加入项目
想使用最新特性或是自行编辑代码,可clone本项目后,采用pip install -e 直接安装到你的django项目目录
更新
- 运行pip install -U wechat-django
- 运行python manage.py migrate 来更新数据库结构
配置
一般而言,默认配置足以满足需求
参数名 | 默认值 | 说明 |
---|---|---|
WECHAT_SITE_HOST | None | 用于接收微信回调的默认域名 |
WECHAT_SITE_HTTPS | True | 接收微信回调域名是否是https |
WECHAT_PATCHADMINSITE | True | 是否将django默认的adminsite替换为wechat_django默认的adminsite, 默认替换 |
WECHAT_SESSIONSTORAGE | "django.core.cache.cache" | 用于存储微信accesstoken等数据的wechatpy.session.SessionStorage 对象,或接收 wechat_django.models.WeChatApp 对象并生成其实例的工厂方法 |
WECHAT_MESSAGETIMEOFFSET | 180 | 微信请求消息时,timestamp与服务器时间差超过该值的请求将被抛弃 |
WECHAT_MESSAGENOREPEATNONCE | True | 是否对微信消息防重放检查 默认检查 |
日志
logger | 说明 |
---|---|
wechat.admin.{appname} | admin异常日志 最低级别warning |
wechat.api.{appname} | api日志 最低级别debug |
wechat.handler.{appname} | 消息处理日志 最低级别debug |
wechat.oauth.{appname} | 网页授权异常日志 最低级别warning |
wechat.site.{appname} | 站点view异常日志(如素材代理) 最低级别warning |
注意事项
- 框架默认采用django的cache管理accesstoken,如果有多个进程,或是多台机器部署,请确保所有worker使用公用cache以免造成token争用,如果希望不使用django的cache管理accesstoken,可以在配置项中定义SessionStorage
- 请确保在https环境下部署,否则有secretkey泄露的风险
部分功能使用说明
网页授权
可通过wechat_django.oauth.wechat_auth
装饰器进行网页授权,授权后,request将被附上一个名为wechat的wechat_django.oauth.WeChatOAuthInfo
对象,可通过 request.wechat.user 拿到wechat_django.models.WeChatUser
实例,通过 request.wechat.app 拿到wechat_django.models.WeChatApp
实例,以下是一个基本示例
from wechat_django import wechat_auth
@wechat_auth("your_app_name")
def your_view(request, *args, **kwargs):
""":type request: wechat_django.requests.WeChatOAuthRequest"""
user = request.wechat.user
对于默认重定向行为不满意的,可以自定义response,具体的参数说明参见wechat_django.oauth.wechat_auth
装饰器的docstring
对于class based view,可继承wechat_django.oauth.WeChatOAuthView
类,具体参见代码
小程序授权
通过wechat_django.models.WeChatApp.auth
进行授权,输入客户端传来的code, 输出一个用户对象以及原始响应.这个方法只能拿到用户的openid与unionid.
from wechat_django.models import WeChatApp
app = WeChatApp.objects.get_by_name("your app name")
user, data = app.auth(code)
对于授权后得到的session_key,框架会持久化至数据库,此后可以通过调用wechat_django.models.WeChatUser.session
来执行相关操作.
auth方法同样适用于网页授权,第二个参数填写网页授权的scope,默认base.
小程序信息加解密及用户数据更新
对于已经进行过小程序授权并且session_key尚未过期的用户,可以使用wechat_django.models.Session.decrypt_message
来解密客户端传来的敏感数据
encrypted_data = ""
iv = ""
try:
data = user.session.decrypt_message(
encrypted_data, iv)
except ValueError:
pass # 无法正确解密数据 session_key可能过期了
亦可使用wechat_django.models.Session.validate_message
来校验客户端传来的数据
from wechatpy.exceptions import InvalidSignatureException
signature = ""
raw_data = ""
try:
data = user.session.validate_message(raw_data, signature)
except InvalidSignatureException:
pass # 签名错误 session_key可能过期了
客户端调用wx.getUserInfo
,可将rawData与signature传递至后端,后端通过调用wechat_django.models.Session.validate_message
与wechat_django.models.User.update
来更新用户信息
from django.http.response import HttpResponse
from wechatpy.exceptions import InvalidSignatureException
signature = request.POST["signature"]
raw_data = request.POST["rawData"]
try:
data = user.session.validate_message(raw_data, signature)
except InvalidSignatureException:
return HttpResponse(status=401)
使用update方法更新用户数据
user.update(data)
主动调用微信api
from wechat_django.models import WeChatApp
app = WeChatApp.get_by_name("your app name")
data = app.client.user.get_followers()
具体client的使用方式,请移步wechatpy文档
自定义微信回复
在后台配置自定义回复,填写自定义回复处理代码的路径,代码须由 wechat_django.handler.message_handler
装饰对应的方法接收一个 wechat_django.models.WeChatMessageInfo
对象,返回字符串或一个 wechatpy.replies.BaseReply
对象
from wechat_django import message_handler
@message_handler
def custom_business(message):
"""
:type message: wechat_django.models.WeChatMessageInfo
"""
user = message.user
msg = message.message
text = "hello, {0}! we received a {1} message.".format(
user, msg.type)
return TextReply(content=text.encode())
微信支付
使用微信支付,需要在INSTALLED_APP的wechat_django
后添加wechat_django.pay
.
统一下单
from wechat_django.models import WeChatApp
app = WeChatApp.objects.get_by_name("your app name")
order = app.pay.create_order(
user="user-instance", body="body", total_fee=1,
out_trade_no="***debug***20190613001") # 也可以用openid="openid"代替user参数
prepay = order.prepay(request)
将jsapi参数交给前端
jsapi_params = order.jsapi_params(prepay["prepay_id"])
主动查询订单状态
order.sync()
订单更新(回调)通知
当订单更新时,会发出wechat_django.pay.signals.order_updated
信号,sender为订单wechat_django.utils.func.Static("{appname}.{payname}")
.信号提供4个变量
变量 | 说明 |
---|---|
result | 订单结果(wechat_django.pay.models.UnifiedOrderResult ) |
order | 更新的订单(wechat_django.pay.models.UnifiedOrder ) |
state | 订单状态(wechat_django.pay.models.UnifiedOrderResult.State ) |
attach | 结果附带的信息(生成订单时传给微信服务器的attach) |
使用示例
from django.dispatch import receiver
from wechat_django.pay import signals
@receiver(signals.order_updated)
def order_updated(result, order, state, attach):
if state == UnifiedOrderResult.State.SUCCESS:
pass
注意! 每次主动调用,微信通知或是后台重新触发都会发送信号,请自行确保订单成功信号逻辑只执行一次!
django-rest-framework
本项目class-based OAuth授权兼容django-rest-framework.
- 构造一个继承
wechat_django.oauth.WeChatOAuthViewMixin
的视图类; - 在视图类中定义
appname
属性; - 根据需要,定义
permission_classes
(如若资源必须授权才可访问,请在permission_classes中添加wechat_django.oauth.WeChatAuthenticated
); - 根据需要,自行处理异常,在
handle_exception
方法中捕获rest_framework.exceptions.NotAuthenticated
,自行处理.
可以参见示例项目的rest.py文件.
后台使用简介
参见管理后台使用简介 文档
示例项目
可参考本项目sample文件夹
TODOS:
- 是否可做成migrate权限全自助?重构权限模块?
- 可选加密存储敏感数据
- Cookbook
- app层面的message log和reply log
- 完善单元测试
- 后台表单验证
计划的功能
- 公众号迁移
- accesstoken开放给第三方并对接第三方accesstoken
- 客服消息/对话
- 清理及保护永久素材
- 回复及一些查询缓存
- 菜单及消息处理程序的导入导出
- 素材Storage
已知bugs
- 多次同步消息处理器会重复生成永久素材
Changelog
Xavier-Lam@NetDragon
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file wechat-django-0.3.2.tar.gz
.
File metadata
- Download URL: wechat-django-0.3.2.tar.gz
- Upload date:
- Size: 113.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d2b98811c83049b6560ea6e15760259de1527dc516b5412287db8c8df42f6693 |
|
MD5 | b5b37de678505f78e2d254975ef3bab9 |
|
BLAKE2b-256 | 7e4f4e066871520f5f06adf6660bfd8d524ac353c6202fbfd695d4e5d6032004 |
File details
Details for the file wechat_django-0.3.2-py2.py3-none-any.whl
.
File metadata
- Download URL: wechat_django-0.3.2-py2.py3-none-any.whl
- Upload date:
- Size: 187.3 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1945a17c90d92cdd6216e873819f78ed211dfa46343390e1757e4d9dc8d5235e |
|
MD5 | cc7ed64446b3ca11186e09db69e3ea38 |
|
BLAKE2b-256 | 68663c841f6a72ee582f1732b195feb5d8e21598636efdb1da42a6ffb9b43b8e |