python 微信开发入门篇-微信扫码签到(四) 项目演示地址:https://www.szyfd.xyz/app/threewall/3dwall 1.新建app  threewall 2.新建static 文件夹,配置静态资源 3.安装 channels  channels_redis 用于处理web socket,pyCryptodome 处理二维码对称加密  4.安装完成后配置如下 settings.py  5.threewall是我们准备建立的签到墙应用,接着就建立我们的 asgi 应用,并指定其要使用的路由。在 settings 同级目录下新建一个 routing.py 的文件: 6.threewall.routing 以及 threewall.routing.websocket_urlpatterns 是我们后面会自己建立的模块。 7.启动redis 8.设计签到表:threewall>models.py 9.threewall>modes.py 10.threewall>views

新建django 项目,如刚接触微信请移步微信开发入门篇第一章:https://www.cnblogs.com/wangcongxing/p/11546780.html

1.新建app  threewall

python manage.py startapp threewall

 python 微信开发入门篇-微信扫码签到(四)
项目演示地址:https://www.szyfd.xyz/app/threewall/3dwall
1.新建app  threewall
2.新建static 文件夹,配置静态资源
3.安装 channels  channels_redis 用于处理web socket,pyCryptodome 处理二维码对称加密
 4.安装完成后配置如下 settings.py 
5.threewall是我们准备建立的签到墙应用,接着就建立我们的 asgi 应用,并指定其要使用的路由。在 settings 同级目录下新建一个 routing.py 的文件:
6.threewall.routing 以及 threewall.routing.websocket_urlpatterns 是我们后面会自己建立的模块。
7.启动redis
8.设计签到表:threewall>models.py
9.threewall>modes.py
10.threewall>views.py

2.新建static 文件夹,配置静态资源

 配置settings.py

STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

 python 微信开发入门篇-微信扫码签到(四)
项目演示地址:https://www.szyfd.xyz/app/threewall/3dwall
1.新建app  threewall
2.新建static 文件夹,配置静态资源
3.安装 channels  channels_redis 用于处理web socket,pyCryptodome 处理二维码对称加密
 4.安装完成后配置如下 settings.py 
5.threewall是我们准备建立的签到墙应用,接着就建立我们的 asgi 应用,并指定其要使用的路由。在 settings 同级目录下新建一个 routing.py 的文件:
6.threewall.routing 以及 threewall.routing.websocket_urlpatterns 是我们后面会自己建立的模块。
7.启动redis
8.设计签到表:threewall>models.py
9.threewall>modes.py
10.threewall>views.py

3.安装 channels  channels_redis 用于处理web socket,pyCryptodome 处理二维码对称加密

pip install -U channels==2.0.2  channels_redis==2.1.1
pip install pyCryptodome

pip install django-simpleui

python 微信开发入门篇-微信扫码签到(四)
项目演示地址:https://www.szyfd.xyz/app/threewall/3dwall
1.新建app  threewall
2.新建static 文件夹,配置静态资源
3.安装 channels  channels_redis 用于处理web socket,pyCryptodome 处理二维码对称加密
 4.安装完成后配置如下 settings.py 
5.threewall是我们准备建立的签到墙应用,接着就建立我们的 asgi 应用,并指定其要使用的路由。在 settings 同级目录下新建一个 routing.py 的文件:
6.threewall.routing 以及 threewall.routing.websocket_urlpatterns 是我们后面会自己建立的模块。
7.启动redis
8.设计签到表:threewall>models.py
9.threewall>modes.py
10.threewall>views.py

 4.安装完成后配置如下 settings.py 

INSTALLED_APPS = [
    'simpleui',
    'import_export',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app',
    'threewall',
    'channels',
]

python 微信开发入门篇-微信扫码签到(四)
项目演示地址:https://www.szyfd.xyz/app/threewall/3dwall
1.新建app  threewall
2.新建static 文件夹,配置静态资源
3.安装 channels  channels_redis 用于处理web socket,pyCryptodome 处理二维码对称加密
 4.安装完成后配置如下 settings.py 
5.threewall是我们准备建立的签到墙应用,接着就建立我们的 asgi 应用,并指定其要使用的路由。在 settings 同级目录下新建一个 routing.py 的文件:
6.threewall.routing 以及 threewall.routing.websocket_urlpatterns 是我们后面会自己建立的模块。
7.启动redis
8.设计签到表:threewall>models.py
9.threewall>modes.py
10.threewall>views.py

5.threewall是我们准备建立的签到墙应用,接着就建立我们的 asgi 应用,并指定其要使用的路由。在 settings 同级目录下新建一个 routing.py 的文件:

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter

import threewall.routing

application = ProtocolTypeRouter({
    # (http->django views is added by default)
    # 普通的HTTP请求不需要我们手动在这里添加,框架会自动加载过来
    'websocket': AuthMiddlewareStack(
        URLRouter(
            threewall.routing.websocket_urlpatterns
        )
    ),
})

6.threewall.routing 以及 threewall.routing.websocket_urlpatterns 是我们后面会自己建立的模块。

紧接着,我们需要在 Django 的配置文件中继续配置 Channels 的 asgi 应用和通道层的信息:

#WSGI_APPLICATION = 'wechatDemo.wsgi.application'
ASGI_APPLICATION = "wechatDemo.routing.application" # 上面新建的 asgi 应用
CHANNEL_LAYERS = {
    'default': {
        # 这里用到了 channels_redis
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            'hosts': [('127.0.0.1', 6379)], # 配置你自己的 redis 服务信息
        },
    }
}

python 微信开发入门篇-微信扫码签到(四)
项目演示地址:https://www.szyfd.xyz/app/threewall/3dwall
1.新建app  threewall
2.新建static 文件夹,配置静态资源
3.安装 channels  channels_redis 用于处理web socket,pyCryptodome 处理二维码对称加密
 4.安装完成后配置如下 settings.py 
5.threewall是我们准备建立的签到墙应用,接着就建立我们的 asgi 应用,并指定其要使用的路由。在 settings 同级目录下新建一个 routing.py 的文件:
6.threewall.routing 以及 threewall.routing.websocket_urlpatterns 是我们后面会自己建立的模块。
7.启动redis
8.设计签到表:threewall>models.py
9.threewall>modes.py
10.threewall>views.py

7.启动redis

windows 安装redis地址:https://www.jianshu.com/p/e16d23e358c0

python 微信开发入门篇-微信扫码签到(四)
项目演示地址:https://www.szyfd.xyz/app/threewall/3dwall
1.新建app  threewall
2.新建static 文件夹,配置静态资源
3.安装 channels  channels_redis 用于处理web socket,pyCryptodome 处理二维码对称加密
 4.安装完成后配置如下 settings.py 
5.threewall是我们准备建立的签到墙应用,接着就建立我们的 asgi 应用,并指定其要使用的路由。在 settings 同级目录下新建一个 routing.py 的文件:
6.threewall.routing 以及 threewall.routing.websocket_urlpatterns 是我们后面会自己建立的模块。
7.启动redis
8.设计签到表:threewall>models.py
9.threewall>modes.py
10.threewall>views.py

8.设计签到表:threewall>models.py

from django.contrib.auth.models import User
from django.db import models
from django.utils.crypto import random
# Create your models here.
from django.utils.html import format_html


# Create your models here.
def rename(newname):
    def decorator(fn):
        fn.__name__ = newname
        return fn
    return decorator

# 签到表
class checkin(models.Model):
    headimgurl = models.URLField(max_length=256, default="", null=True, blank=True)
    openid = models.CharField(max_length=225, verbose_name="openid", blank=True, default="")
    nickname = models.CharField(max_length=225, verbose_name="昵称", blank=True, default="")
    sex = models.CharField(max_length=225, verbose_name="性别", blank=True, default="")
    language = models.CharField(max_length=225, verbose_name="语言", blank=True, default="")
    city = models.CharField(max_length=225, verbose_name="城市", blank=True, default="")

    createTime = models.DateTimeField(auto_now_add=True, verbose_name="签到时间")
    lastTime = models.DateTimeField(auto_now=True, verbose_name="修改时间")

    class Meta:
        verbose_name_plural = "签到表"

    @rename("模板头像")
    def showheadimgurl(self):
        return format_html("<img src='{}' style='50px'/>", self.headimgurl)

    def __str__(self):
        return self.nickname

9.threewall>modes.py

from django.contrib import admin
from threewall import models


# Register your models here.
@admin.register(models.checkin)
class orderAdmin(admin.ModelAdmin):
    list_display = ("showheadimgurl", "openid", "nickname", "sex", "language", "city", "createTime", "lastTime")
    list_display_links = ("openid", "nickname")
    search_fields = ('nickname', "openid")
    list_per_page = 50

10.threewall>views.py

from django.shortcuts import render
from wechatpy.oauth import WeChatOAuth
from django.shortcuts import render, redirect
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
import time
import datetime
from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render
import uuid
from wechatpy import WeChatClient
import os
import json
from wechatpy import WeChatPay
from threewall import models
from wechatpy.pay import dict_to_xml
import base64
from Crypto.Cipher import AES

# Create your views here.

# 公众号id
AppID = "xxx"
# 公众号AppSecret
AppSecret = "xxx"

# 密钥
key = "xxxx"
# 服务号
client = WeChatClient(AppID, AppSecret)

# 消息通道
from channels.layers import get_channel_layer

channel_layer = get_channel_layer()
from asgiref.sync import async_to_sync


# Create your views here.

def dwall(request):
    checkins = models.checkin.objects.values("headimgurl")[0:200]
    print(checkins.query)
    checkUserInfo = []
    CurPersonNum = checkins.count()
    for item in checkins:
        checkUserInfo.append({"headimgurl": item["headimgurl"]})
    if checkUserInfo.__len__() < 199:
        index = 0
        while index < (199 - checkUserInfo.__len__()):
            index += 1
            checkUserInfo.append({"headimgurl": "/static/3dwall/img/a.png"})

    aes = AES.new(add_to_16(key), AES.MODE_ECB)
    # 先进行aes加密
    ticks = str(time.time())
    encrypt_aes = aes.encrypt(add_to_16(ticks))
    # 用base64转成字符串形式
    encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8')  # 执行加密并转码返回bytes

    return render(request, "3dwall.html",
                  {"checkUserInfo": checkUserInfo, "CurPersonNum": CurPersonNum, "encrypted_text": encrypted_text})


# 定义授权装饰器

def getWeChatOAuth(redirect_url):
    return WeChatOAuth(AppID, AppSecret, redirect_url, 'snsapi_userinfo')


def oauth(method):
    def warpper(request):
        if request.session.get('user_info', None) is None:
            code = request.GET.get('code', None)
            wechat_oauth = getWeChatOAuth(request.get_raw_uri())
            url = wechat_oauth.authorize_url
            print(url)
            if code:
                try:
                    wechat_oauth.fetch_access_token(code)
                    user_info = wechat_oauth.get_user_info()
                    print(user_info)
                except Exception as e:
                    print(str(e))
                    # 这里需要处理请求里包含的 code 无效的情况
                    # abort(403)
                else:
                    # 建议存储在用户表
                    request.session['user_info'] = user_info
            else:
                return redirect(url)
        return method(request)

    return warpper


@oauth
def checkin(request):
    signature = request.GET.get("signature", None)
    if signature is None:
        return render(request, "checkerror.html")
    try:
        aes = AES.new(add_to_16(key), AES.MODE_ECB)
        # 优先逆向解密base64成bytes
        base64_decrypted = base64.decodebytes(signature.replace(' ', '+').encode(encoding='utf-8'))
        # 执行解密密并转码返回str
        decrypted_text = str(aes.decrypt(base64_decrypted), encoding='utf-8').replace('