python 全栈开发,Day103(微信消息推送,结算中心业务流程)
python 全棧開發(fā),Day103(微信消息推送,結(jié)算中心業(yè)務(wù)流程)
昨日內(nèi)容回顧
第一部分:考試題(Python基礎(chǔ))第二部分:路飛相關(guān) 1. 是否遇到bug?難解決的技術(shù)點(diǎn)?印象深刻的事?- orm操作費(fèi)勁- 最開始學(xué)習(xí)路由系統(tǒng)時(shí)候,匹配規(guī)則;答案一:有,但主要不是在技術(shù)上而是在業(yè)務(wù)上;在支付時(shí):貝里、支付寶、滿減、立減、折扣;答案二:編寫API時(shí),如果繼承ModelViewSet相關(guān)的類之后,必須在靜態(tài)字段中寫:querysetclass AuthView(ModelViewSet):queryset = models.xxx.all()否則,在渲染器渲染好看的頁面時(shí),會(huì)報(bào)錯(cuò)。解決方案:a. 不繼承,繼承APIViewb. 定義渲染器class AuthView(GenaricViewSet):render_classes = [JSONrender,]queryset = models.xxx.all()答案三:在剛學(xué)習(xí)時(shí)候,xxxxxxx大忌:非常簡(jiǎn)單的功能 2. 路飛學(xué)城項(xiàng)目架構(gòu)是怎么樣?- 管理后臺(tái)- 導(dǎo)師后臺(tái)- 主站 - 前端:1人 - 后端:3人(1+0.5+1+0.5+0.5)- UI:1人 3. 路飛學(xué)城中你負(fù)責(zé)寫過什么?API:- 第一類:基本增刪改查- 課程列表- 學(xué)位課- 專題課- 課程詳細(xì)- 課程大綱 - 價(jià)格策略- 推薦課程- 課程章節(jié) - 用戶評(píng)價(jià)- 常見問題- 文章列表- 文章詳細(xì)- 評(píng)論- 點(diǎn)贊- 收藏- 學(xué)習(xí)中心- 我的賬戶- 我的訂單- 作業(yè)- 回答- 提問...- 第二類:支付流程- 購物車- 加入購物車- 查看 - 修改價(jià)格策略- 刪除購物車中的課程 4. 路飛學(xué)城購物車的結(jié)構(gòu)? View Code?
一、微信消息推送
面對(duì)大量的垃圾信息擬門會(huì)報(bào)告垃圾短信,導(dǎo)致了大部分消息推送方式的失效或者效果打折,今天談的是效果非常好的微信通知服務(wù)
因?yàn)檫@里推送的都是有效信息,屏蔽的人非常少,微信不允許你把它當(dāng)做推廣工具,所以都有調(diào)用次數(shù)等規(guī)則限制,但我們可以好好利用以保持應(yīng)用的用戶粘性。
公眾號(hào)
公眾號(hào)分別3種:訂閱號(hào),服務(wù)號(hào),企業(yè)號(hào)。
其中訂閱號(hào),分為未認(rèn)證和已認(rèn)證。已認(rèn)證需要公司營業(yè)執(zhí)照相關(guān)信息,服務(wù)號(hào)和企業(yè)號(hào),也需要公司相關(guān)信息。
基于沙箱環(huán)境做消息推送
由于用戶體驗(yàn)和安全性方面的考慮,微信公眾號(hào)的注冊(cè)有一定門檻,某些高級(jí)接口的權(quán)限需要微信認(rèn)證后才可以獲取。
所以,為了幫助開發(fā)者快速了解和上手微信公眾號(hào)開發(fā),熟悉各個(gè)接口的調(diào)用,我們推出了微信公眾帳號(hào)測(cè)試號(hào),通過手機(jī)微信掃描二維碼即可獲得測(cè)試號(hào)。
進(jìn)入微信公眾帳號(hào)測(cè)試號(hào)申請(qǐng)系統(tǒng)
單擊登錄,掃描一下二維碼
打開手機(jī)微信,確認(rèn)登錄
進(jìn)入之后,就會(huì)有一個(gè)測(cè)試賬號(hào)
接下來的代碼,需要使用appID和appsecret
網(wǎng)頁的表單,一律不需要填寫!!!
?
找到下面的測(cè)試好二維碼,將圖片下載下來
直接右鍵-->另存為即可
項(xiàng)目測(cè)試
新建一個(gè)項(xiàng)目wxbox,注意:django版本為1.11
修改urls.py
from django.conf.urls import url from django.contrib import adminfrom app01 import views urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^index/', views.index), ] View Code將templates目錄剪切到app01目錄下,在app01目錄下,創(chuàng)建static。為什么這么做呢?
因?yàn)檫@樣的話,每一個(gè)應(yīng)用都有獨(dú)立的templates和static。
那么django能找到它嗎?
默認(rèn)是從項(xiàng)目根目錄查找,如果找不到,會(huì)從應(yīng)用名目錄中取找。找不到,就報(bào)錯(cuò)!
?
將下載的圖片放到static中,新建index.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <h1>歡迎使用:路飛學(xué)城</h1><h3>掃描關(guān)注路飛學(xué)誠(用于消息提示,請(qǐng)必須關(guān)注)</h3> <img style="width: 200px;" src="/static/0.jpg" alt=""></body> </html> View Code修改views.py
from django.shortcuts import render,HttpResponse# Create your views here. def index(request):"""首頁:param request::return:"""return render(request,"index.html") View Code啟動(dòng)django項(xiàng)目,訪問首頁
獲取用戶的微信id
使用另外一個(gè)微信號(hào),掃描一下,點(diǎn)擊關(guān)注
這里會(huì)出現(xiàn)一個(gè)微信號(hào)
?注意:這里的微信號(hào),并不是真正的微信號(hào),它是一段隨機(jī)碼。它只是和這個(gè)公眾號(hào)做了一下綁定,為了唯一標(biāo)識(shí)這個(gè)用戶!
假設(shè)這個(gè)用戶,由關(guān)注了別的公眾號(hào)。那么會(huì)出現(xiàn)一個(gè)新的隨機(jī)碼!
也就是說:不同公眾號(hào),同一個(gè)人,是不一樣的!
?
腳本測(cè)試
使用前,安裝模塊
pip3 install requests獲取token
因?yàn)橐蛴脩舭l(fā)送消息,所以需要使用token認(rèn)證,才能發(fā)送!
?
在項(xiàng)目根目錄創(chuàng)建? test.py
注意:修改里面的appid和secret,改為自己的
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import requests# 1. 偽造瀏覽器向 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential... 發(fā)送GET請(qǐng)求,并獲取token r1 = requests.get(url="https://api.weixin.qq.com/cgi-bin/token",params={"grant_type": "client_credential","appid": 'wx038ba9d6c87fxxxx',"secret": 'fd1ebdff49010aa67a1457bbe250xxxx',} )print(r1.text) # 獲取文本 print('*'*30) print(r1.json()) # 反序列化 print('*'*30)access_token = r1.json().get('access_token') # 獲取token print(access_token) View Code執(zhí)行輸出:
{"access_token":"12_23d1iIREKvhS0N6EislyKdaV9MhcaXgBAgTnH_5ivrobK4Ek6uoD9_35nvlL8SO76dGQ-T6wnzmVaXi3wHhCigaw85JqMV47DM0rq664ZEYdfOWypvyplByJ6yts-F3RYthMkWtfG-bGyyzDYZVfADAGHD","expires_in":7200} ****************************** {'expires_in': 7200, 'access_token': '12_23d1iIREKvhS0N6EislyKdaV9MhcaXgBAgTnH_5ivrobK4Ek6uoD9_35nvlL8SO76dGQ-T6wnzmVaXi3wHhCigaw85JqMV47DM0rq664ZEYdfOWypvyplByJ6yts-F3RYthMkWtfG-bGyyzDYZVfADAGHD'} ****************************** 12_23d1iIREKvhS0N6EislyKdaV9MhcaXgBAgTnH_5ivrobK4Ek6uoD9_35nvlL8SO76dGQ-T6wnzmVaXi3wHhCigaw85JqMV47DM0rq664ZEYdfOWypvyplByJ6yts-F3RYthMkWtfG-bGyyzDYZVfADAGHD View Code給指定用戶發(fā)送消息
復(fù)制這里面的微信號(hào),它可以定位到這個(gè)用戶
?
修改test.py,指定微信號(hào)
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import requests# 1. 偽造瀏覽器向 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential... 發(fā)送GET請(qǐng)求,并獲取token r1 = requests.get(url="https://api.weixin.qq.com/cgi-bin/token",params={"grant_type": "client_credential","appid": 'wx038ba9d6c87fxxxx',"secret": 'fd1ebdff49010aa67a1457bbe250dxxx',} )# print(r1.text) # 獲取文本 # print('*'*30) # print(r1.json()) # 反序列化 # print('*'*30) access_token = r1.json().get('access_token') # 獲取token # print(access_token)# 2. 給指定用戶發(fā)送普通消息消息:access_token/ wx_id = 'oe0j758m-Zp4QBOvgzF8vGBCOxxx' # 微信號(hào) body = {"touser": wx_id,"msgtype": "text", # 本文"text": {"content": 'hello'} }r2 = requests.post(url="https://api.weixin.qq.com/cgi-bin/message/custom/send",params={'access_token': access_token},# 發(fā)送的消息,必須是bytes類型data=bytes(json.dumps(body,ensure_ascii=False),encoding='utf-8') )print(r2.text) View Code解釋:request,內(nèi)部發(fā)送的數(shù)據(jù)是字節(jié)。默認(rèn)格式為L(zhǎng)atin-1,它不支持中文!
所以需要使用json序列化。如果發(fā)送的是字符串,它會(huì)使用Latin-1轉(zhuǎn)碼為bytes,遇到中文會(huì)報(bào)錯(cuò)
所以我這里,直接強(qiáng)轉(zhuǎn)為bytes,那么它內(nèi)部就不會(huì)轉(zhuǎn)碼了,直接發(fā)送!
?
執(zhí)行腳本,輸出:
{"errcode":0,"errmsg":"ok"}看狀態(tài),發(fā)送成功。
查看用戶接收的消息
?
發(fā)送模板消息
發(fā)送模板消息,腳本需要指定新的url
https://api.weixin.qq.com/cgi-bin/message/template/send默認(rèn)這里是空的,點(diǎn)擊新建測(cè)試模板
注意:參數(shù)需以{{開頭,以.DATA}}結(jié)尾。模板標(biāo)題不能使用參數(shù)
這里的user,就是用戶的微信名
?接下發(fā)送時(shí),需要這個(gè)模板id
?
修改test.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import requests# 1. 偽造瀏覽器向 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential... 發(fā)送GET請(qǐng)求,并獲取token r1 = requests.get(url="https://api.weixin.qq.com/cgi-bin/token",params={"grant_type": "client_credential","appid": 'wx038ba9d6c87fxxxx',"secret": 'fd1ebdff49010aa67a1457bbe250xxx',} )access_token = r1.json().get('access_token') # 獲取token # print(access_token)# 2. 給指定用戶發(fā)送普通消息消息:access_token/ wx_id = 'oe0j758m-Zp4QBOvgzF8vGBCOxxx' # 微信號(hào) body = {"touser": wx_id,"template_id": 'OxCBr-98eVMkTLKb0ZGpLGK5mNnLMLoEZG2MsmR3Q_Q', # 模板id"data": {"user": {"value": "小明同學(xué)","color": "#173177"}} }r2 = requests.post(url="https://api.weixin.qq.com/cgi-bin/message/template/send",params={'access_token': access_token},data=json.dumps(body) )print(r2.text) View Code執(zhí)行腳本,輸出:
{"errcode":0,"errmsg":"ok","msgid":412032057779486721}查看手機(jī)消息
推送消息,一天可以發(fā)送10萬次
這里演示的向用戶發(fā)送推送消息,必須讓用戶關(guān)注公眾號(hào)。從公眾號(hào)后臺(tái)的用戶列表中,得到用戶的微信號(hào)(隨機(jī)字符串)
才可以準(zhǔn)確發(fā)送到用戶手機(jī)上,只有管理者,才能看到這個(gè)微信號(hào)
?
自動(dòng)獲取用戶-消息發(fā)送
上面的腳本,演示的是手動(dòng)發(fā)送。如果用戶過多,發(fā)送消息會(huì)很繁瑣!
如何讓用戶做簡(jiǎn)單的操作,就能自動(dòng)發(fā)送消息給用戶呢?
?
路飛學(xué)城購買課程之后,不能直接觀看視頻。要填寫報(bào)名表才能觀看!
填寫相關(guān)信息后,發(fā)送微信消息
這里只做簡(jiǎn)單的功能:讓用戶掃描二維碼,將微信號(hào)自動(dòng)存儲(chǔ)在數(shù)據(jù)庫中,并發(fā)送消息
?
創(chuàng)建用戶表
修改models.py
from django.db import modelsclass UserInfo(models.Model):name = models.CharField(max_length=32,verbose_name="用戶名")pwd = models.CharField(max_length=64,verbose_name="密碼")wx_id = models.CharField(max_length=32,null=True,blank=True,verbose_name="微信號(hào)") View Code執(zhí)行2個(gè)命令,生成表
python manage.py makemigrations python manage.py migrate使用navicat打開sqlite3數(shù)據(jù)庫
添加一條記錄,微信號(hào)保持為空
用戶登錄
修改urls.py,增加路徑
urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^index/', views.index),url(r'^login/', views.login), ] View Code新建login.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <form method="post">{% csrf_token%}<input type="text" name="user"><input type="text" name="pwd"><input type="submit" value="提交">{{ msg }} </form> </body> </html> View Code修改views.py
from django.shortcuts import render,HttpResponse,redirect from app01 import models# Create your views here. def login(request):"""用戶登陸:param request::return:"""if request.method == 'GET':return render(request, 'login.html')user = request.POST.get('user')pwd = request.POST.get('pwd')obj = models.UserInfo.objects.filter(name=user, pwd=pwd).first()if obj:request.session['user_info'] = {'id': obj.id, 'name': obj.name}return redirect('/index/')return render(request, 'login.html', {'msg': '用戶名或密碼錯(cuò)誤'})def index(request):"""首頁:param request::return:"""return render(request,"index.html") View Code修改index.html,顯示登錄用戶名
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <h1>歡迎 {{ request.session.user_info.name }} 使用:路飛學(xué)城</h1><h3>掃描關(guān)注路飛學(xué)誠(用于消息提示,請(qǐng)必須關(guān)注)</h3> <img style="width: 200px;" src="/static/0.jpg" alt=""></body> </html> View Code訪問登錄頁面
登錄之后,效果如下:
下一步,需要獲取用戶的微信號(hào)
怎么獲取呢?讓用戶訪問一個(gè)鏈接,執(zhí)行上面的腳本,得到用戶的微信號(hào),并存入數(shù)據(jù)庫!
?
js生成二維碼
jquery.qrcode.js 是一個(gè)能夠在客戶端生成矩陣二維碼QRCode 的jquery插件 ,使用它可以很方便的在頁面上生成二維條碼。
如何使用它
將jquery.qrcode.min.js和jquery添加到您的網(wǎng)頁中
<script src="jquery.min.js"></script> <script type="text/javascript" src="jquery.qrcode.min.js"></script>然后創(chuàng)建一個(gè)DOM元素去包含生成qr碼。
<div id="qrcode"></div>最后你在此容器中的添加qrcode
<script>jQuery(function(){jQuery('#qrcode').qrcode("http://www.jq22.com"); }) </script>就這么簡(jiǎn)單,您想要的二維碼就生成了。
?
在static目錄中創(chuàng)建js目錄,將3個(gè)文件jquery.min.js,jquery.qrcode.min.js,qrcode.js放到此目錄
修改index.html,生成二維碼
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <h1>歡迎 {{ request.session.user_info.name }} 使用:路飛學(xué)城</h1><h3>掃描關(guān)注路飛學(xué)誠(用于消息提示,請(qǐng)必須關(guān)注)</h3> <img style="width: 200px;" src="/static/0.jpg" alt=""><script src="/static/js/jquery.min.js"></script> <script src="/static/js/jquery.qrcode.min.js"></script> <script src="/static/js/qrcode.js"></script> <script>$(function () {// empty()表示清空// text表示內(nèi)容$('#qrcode').empty().qrcode({text: 'http://www.py3study.com/'});}) </script></body> </html> View Code刷新index頁面,效果如下:
用戶掃描最下面的二維碼,就會(huì)自動(dòng)打開網(wǎng)頁:?http://www.py3study.com/
?
獲取微信號(hào)并寫入數(shù)據(jù)庫
獲取微信號(hào),需要在這里配置回調(diào)的url,點(diǎn)擊修改
通過該接口,可以獲取用戶的基本信息(獲取用戶的OpenID是無需用戶同意的,獲取用戶的基本信息則需用戶同意)
?
這里必須公網(wǎng)IP才行
注意:冒號(hào)不能是中文!!!否則報(bào)url不匹配
?
?
線上部署
登錄到公網(wǎng)服務(wù)器,將項(xiàng)目拷貝過去
注意:python版本為3.5,django版本為1.11
安裝requests
pip3 install requests修改urls.py,增加路徑
urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^index/', views.index),url(r'^login/', views.login),url(r'^get_qrcode/', views.get_qrcode),url(r'^get_wx_id/', views.get_wx_id), ] View Code修改settings.py,運(yùn)行所有IP訪問
ALLOWED_HOSTS = ['*',]修改views.py,增加視圖函數(shù)
注意:修改appid,secret改成自己的。redirect_uri改成自己的公網(wǎng)IP和端口
from django.shortcuts import render, redirect from app01 import models from django.http import JsonResponse, HttpResponse# Create your views here. def login(request):"""用戶登陸:param request::return:"""if request.method == 'GET':return render(request, 'login.html')user = request.POST.get('user')pwd = request.POST.get('pwd')obj = models.UserInfo.objects.filter(name=user, pwd=pwd).first()if obj:request.session['user_info'] = {'id': obj.id, 'name': obj.name}return redirect('/index/')return render(request, 'login.html', {'msg': '用戶名或密碼錯(cuò)誤'})def index(request):"""首頁:param request::return:"""return render(request, "index.html")def get_qrcode(request):"""訪問獲取用戶基本信息接口需要接收3個(gè)參數(shù):param request::return:"""ret = {'status': True, 'data': None}# appid 是自己的appid# redirect_uri 是回調(diào)地址,騰訊服務(wù)器會(huì)訪問它# state是自定義的,變量名可以隨意access_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={appid}&redirect_uri={redirect_uri}&response_type=code&scope=snsapi_userinfo&state={state}#wechat_redirect"url = access_url.format(appid='wx038ba9d6c87fxxxx',redirect_uri="http://45.xx.192.14:8000/get_wx_id/", # 跳轉(zhuǎn)會(huì)我的網(wǎng)站state=request.session['user_info']['id'] # 用戶ID )ret['data'] = url # 生成urlreturn JsonResponse(ret) # 返回給ajaxdef get_wx_id(request):"""獲取微信ID,并更新到數(shù)據(jù)庫:param request::return:"""import requestscode = request.GET.get("code")state = request.GET.get("state")# 獲取該用戶openId(用戶唯一,用于給用戶發(fā)送消息)r1 = requests.get(url="https://api.weixin.qq.com/sns/oauth2/access_token",params={"appid": 'wx038ba9d6c87fxxxx',"secret": 'fd1ebdff49010aa67a1457bbe250xxxx',"code": code,"grant_type": 'authorization_code',}).json()# 獲取的到openid表示用戶授權(quán)成功wx_id = r1.get("openid")user = models.UserInfo.objects.filter(id=state).first()# 判斷用戶id不為空if not user.wx_id:user.wx_id = wx_iduser.save() # 修改微信idreturn HttpResponse('授權(quán)成功') View Code修改index.html,增加ajax
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <h1>歡迎 {{ request.session.user_info.name }} 使用:路飛學(xué)城</h1><h3>掃描關(guān)注路飛學(xué)誠(用于消息提示,請(qǐng)必須關(guān)注)</h3> <img style="width: 250px;" src="/static/0.jpg" alt=""><h3>下一步:請(qǐng)將微信ID發(fā)給我</h3> <div id="qrcode" style="width: 250px;height: 250px;background-color: white;"></div><script src="/static/js/jquery.min.js"></script> <script src="/static/js/jquery.qrcode.min.js"></script> <script src="/static/js/qrcode.js"></script> <script>$(function () {get_qcode();});function get_qcode() {$.ajax({url: '/get_qrcode/',type: 'GET',dataType: 'JSON',success: function (arg) {//arg.data 就是訪問獲取用戶基本信息接口的url地址// 需要接收3個(gè)參數(shù)$('#qrcode').empty().qrcode({text: arg.data});console.log(arg.data);}})} </script></body> </html> View Code訪問公網(wǎng)的登錄地址
登錄成功后,進(jìn)入首頁
可以發(fā)現(xiàn)最下面的二維碼,更加復(fù)雜了。因?yàn)槔锩婕恿撕荛L(zhǎng)的url
查看console
使用手機(jī)掃描二維碼,它其實(shí)就是訪問上面很長(zhǎng)的url
點(diǎn)擊允許
點(diǎn)擊繼續(xù)訪問
提示授權(quán)成功
查看服務(wù)器的終端輸出
它先訪問的是get_qrcode
get_wx_id是騰訊訪問的
將sqlite3下載下來,使用navicat查看數(shù)據(jù)庫
發(fā)現(xiàn)微信id更新了
?
?
網(wǎng)頁點(diǎn)擊發(fā)送消息
單獨(dú)做一個(gè)頁面,點(diǎn)擊指定的用戶,發(fā)送消息
修改urls.py,增加路徑
urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^index/', views.index),url(r'^login/', views.login),url(r'^get_qrcode/', views.get_qrcode),url(r'^get_wx_id/', views.get_wx_id),url(r'^send/', views.send),url(r'^send_msg/', views.send_msg), ] View Code修改views.py
from django.shortcuts import render,redirect from app01 import models from django.http import JsonResponse, HttpResponse# Create your views here. def login(request):"""用戶登陸:param request::return:"""if request.method == 'GET':return render(request, 'login.html')user = request.POST.get('user')pwd = request.POST.get('pwd')obj = models.UserInfo.objects.filter(name=user, pwd=pwd).first()if obj:request.session['user_info'] = {'id': obj.id, 'name': obj.name}return redirect('/index/')return render(request, 'login.html', {'msg': '用戶名或密碼錯(cuò)誤'})def index(request):"""首頁:param request::return:"""return render(request,"index.html")def get_qrcode(request):"""訪問獲取用戶基本信息接口需要接收3個(gè)參數(shù):param request::return:"""ret = {'status': True, 'data': None}# appid 是自己的appid# redirect_uri 是回調(diào)地址,騰訊服務(wù)器會(huì)訪問它# state是自定義的,變量名可以隨意access_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={appid}&redirect_uri={redirect_uri}&response_type=code&scope=snsapi_userinfo&state={state}#wechat_redirect"url = access_url.format(appid='wx038ba9d6c87fxxxx',redirect_uri="http://45.xx.192.14:8000/get_wx_id/", # 跳轉(zhuǎn)會(huì)我的網(wǎng)站state=request.session['user_info']['id'] # 用戶ID )ret['data'] = url # 生成urlreturn JsonResponse(ret) # 返回給ajaxdef get_wx_id(request):"""獲取微信ID,并更新到數(shù)據(jù)庫:param request::return:"""import requestscode = request.GET.get("code")state = request.GET.get("state")# 獲取該用戶openId(用戶唯一,用于給用戶發(fā)送消息)r1 = requests.get(url="https://api.weixin.qq.com/sns/oauth2/access_token",params={"appid": 'wx038ba9d6c87fxxxx',"secret": 'fd1ebdff49010aa67a1457bbe250xxxx',"code": code,"grant_type": 'authorization_code',}).json()# 獲取的到openid表示用戶授權(quán)成功wx_id = r1.get("openid")user = models.UserInfo.objects.filter(id=state).first()# 判斷用戶id不為空if not user.wx_id:user.wx_id = wx_iduser.save() # 修改微信idreturn HttpResponse('授權(quán)成功')def send(request):"""發(fā)送消息:param request::return:"""user_list = models.UserInfo.objects.all()return render(request, 'send.html', {'user_list': user_list})def send_msg(request):"""發(fā)送消息:param request::return:"""id = request.session['user_info']['id']obj = models.UserInfo.objects.filter(id=id).first()import jsonimport requests# 1. 偽造瀏覽器向 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential... 發(fā)送GET請(qǐng)求,并獲取tokenr1 = requests.get(url="https://api.weixin.qq.com/cgi-bin/token",params={"grant_type": "client_credential","appid": 'wx038ba9d6c87fxxxx',"secret": 'fd1ebdff49010aa67a1457bbe250xxxx',})access_token = r1.json().get('access_token')body = {"touser": obj.wx_id,"template_id": 'OxCBr-98eVMkTLKb0ZGpLGK5mNnLMLoEZG2MsmR3Q_Q',"data": {"user": {"value": "Hello Kitty","color": "#173177"}}}r2 = requests.post(url="https://api.weixin.qq.com/cgi-bin/message/template/send",params={'access_token': access_token},data=json.dumps(body))print(r2.text)return HttpResponse('發(fā)送成功') View Code創(chuàng)建send.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><ul>{% for item in user_list %}<li>{{ item.name }} {{ item.wx_id }} <a href="/send_msg/">發(fā)送消息</a></li>{% endfor %}</ul> </body> </html> View Code訪問頁面,點(diǎn)擊發(fā)送消息
提示發(fā)送成功
?查看手機(jī)信息
?
?
流程圖
?
解釋:
1. 瀏覽器訪問服務(wù)器的登錄頁面
2. 服務(wù)器返回登錄成功,跳轉(zhuǎn)首頁。并生成底部的二維碼,鏈接就是獲取個(gè)人信息的
3. 用戶掃描二維碼,關(guān)注公眾號(hào)
4. 引導(dǎo)用戶進(jìn)入授權(quán)頁面同意授權(quán),用戶掃描下面的二維碼
5. 用戶手機(jī)訪問鏈接,用來獲取微信個(gè)人信息的
6. 微信服務(wù)器獲取個(gè)人信息,訪問回調(diào)地址redirect_uri,也就是個(gè)人服務(wù)器。
7. 個(gè)人服務(wù)器訪問微信服務(wù)器,通過code換取網(wǎng)頁授權(quán)access_token(與基礎(chǔ)支持中的access_token不同)
8. 微信服務(wù)器將個(gè)人信息返回給服務(wù)器,服務(wù)器更新數(shù)據(jù)庫
?
?總結(jié):
a.路飛中使用的是已認(rèn)證的服務(wù)號(hào)b.基于微信ID發(fā)送消息- 獲取AccessToken- 發(fā)送消息:- AccessToken- 微信ID- 消息內(nèi)容注意:AccessToken的超時(shí)時(shí)間8小時(shí)c.誘導(dǎo)用戶發(fā)送微信ID"間接"給我步驟: 1. 申請(qǐng)沙箱環(huán)境賬號(hào)2. 手動(dòng)發(fā)送消息3. 寫django程序: - 創(chuàng)建用戶表:wx_id- 登陸頁面- "填寫報(bào)名報(bào)" 掃碼- 公眾號(hào)- 授權(quán)碼,基于qrcode.js庫完成+ajax從后臺(tái)獲取的要跳轉(zhuǎn)的地址(騰訊)- 公眾號(hào)后臺(tái)設(shè)置:網(wǎng)頁授權(quán)獲取用戶基本信息 --> xx.xx.xx.xx:8000- redirect_uri指定要要跳轉(zhuǎn)的地址4. - 回調(diào)函數(shù),從騰訊中獲取用戶微信ID并更新到自己數(shù)據(jù)庫- 獲取微信ID,并更新到數(shù)據(jù)庫- 獲取該用戶openId- 獲取的到openid表示用戶授權(quán)成功- 更新數(shù)據(jù)庫 5.頁面發(fā)送- 用戶列表- 要發(fā)送的內(nèi)容- 按鈕:發(fā)送- 1. 偽造瀏覽器向公眾號(hào)發(fā)送GET請(qǐng)求,并獲取token- 2. 給指定用戶發(fā)送普通消息消息- 3. 給指定用戶發(fā)送模板消息 View Code?
將appid,secretredirect_uri 移植到settings.py中
完整代碼請(qǐng)參考github
https://github.com/987334176/WeChat
?
二、結(jié)算中心業(yè)務(wù)流程
購物車3個(gè)狀態(tài):放入購物車,結(jié)算,支付
結(jié)算頁面
進(jìn)入結(jié)算頁面,購物車不會(huì)清空。只有支付成功后,才會(huì)刪除購物車的商品!
結(jié)算中心和購物車一樣,是一個(gè)中間狀態(tài),可以刪除/修改價(jià)格策略
它比購物車,多了一個(gè)字段-->優(yōu)惠券
?
優(yōu)惠券這里面涉及的邏輯,就比較復(fù)雜了
由于時(shí)間關(guān)系,沒法一一細(xì)說。
直接上表結(jié)構(gòu)
下載最后一個(gè)版本的代碼
https://github.com/987334176/luffycity/archive/v1.5.zip
?
修改models.py,增加3個(gè)表。注意:course要開啟優(yōu)惠券
完整代碼如下:
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType from django.db.models import Q from django.utils.safestring import mark_safe from django.db import models import hashlib# ######################## 課程相關(guān) ########################class CourseCategory(models.Model):"""課程大類, e.g 前端 后端..."""name = models.CharField(max_length=64, unique=True)def __str__(self):return "%s" % self.nameclass Meta:verbose_name_plural = "01.課程大類"class CourseSubCategory(models.Model):"""課程子類, e.g python linux """category = models.ForeignKey("CourseCategory")name = models.CharField(max_length=64, unique=True)def __str__(self):return "%s" % self.nameclass Meta:verbose_name_plural = "02.課程子類"class DegreeCourse(models.Model):"""學(xué)位課程"""name = models.CharField(max_length=128, unique=True)course_img = models.CharField(max_length=255, verbose_name="縮略圖")brief = models.TextField(verbose_name="學(xué)位課程簡(jiǎn)介", )total_scholarship = models.PositiveIntegerField(verbose_name="總獎(jiǎng)學(xué)金(貝里)", default=40000) # 2000 2000mentor_compensation_bonus = models.PositiveIntegerField(verbose_name="本課程的導(dǎo)師輔導(dǎo)費(fèi)用(貝里)", default=15000)period = models.PositiveIntegerField(verbose_name="建議學(xué)習(xí)周期(days)", default=150) # 為了計(jì)算學(xué)位獎(jiǎng)學(xué)金prerequisite = models.TextField(verbose_name="課程先修要求", max_length=1024)teachers = models.ManyToManyField("Teacher", verbose_name="課程講師")# 用于GenericForeignKey反向查詢, 不會(huì)生成表字段,切勿刪除# coupon = GenericRelation("Coupon")# 用于GenericForeignKey反向查詢,不會(huì)生成表字段,切勿刪除degreecourse_price_policy = GenericRelation("PricePolicy")def __str__(self):return self.nameclass Meta:verbose_name_plural = "03.學(xué)位課"class Teacher(models.Model):"""講師、導(dǎo)師表"""name = models.CharField(max_length=32)role_choices = ((0, '講師'), (1, '導(dǎo)師'))role = models.SmallIntegerField(choices=role_choices, default=0)title = models.CharField(max_length=64, verbose_name="職位、職稱")signature = models.CharField(max_length=255, help_text="導(dǎo)師簽名", blank=True, null=True)image = models.CharField(max_length=128)brief = models.TextField(max_length=1024)def __str__(self):return self.nameclass Meta:verbose_name_plural = "04.導(dǎo)師或講師"class Scholarship(models.Model):"""學(xué)位課程獎(jiǎng)學(xué)金"""degree_course = models.ForeignKey("DegreeCourse")time_percent = models.PositiveSmallIntegerField(verbose_name="獎(jiǎng)勵(lì)檔位(時(shí)間百分比)", help_text="只填百分值,如80,代表80%")value = models.PositiveIntegerField(verbose_name="獎(jiǎng)學(xué)金數(shù)額")def __str__(self):return "%s:%s" % (self.degree_course, self.value)class Meta:verbose_name_plural = "05.學(xué)位課獎(jiǎng)學(xué)金"class Course(models.Model):"""專題課/學(xué)位課模塊表"""name = models.CharField(max_length=128, unique=True)course_img = models.CharField(max_length=255)sub_category = models.ForeignKey("CourseSubCategory")course_type_choices = ((0, '付費(fèi)'), (1, 'VIP專享'), (2, '學(xué)位課程'))course_type = models.SmallIntegerField(choices=course_type_choices)# 不為空;學(xué)位課的某個(gè)模塊# 為空;專題課degree_course = models.ForeignKey("DegreeCourse", blank=True, null=True, help_text="若是學(xué)位課程,此處關(guān)聯(lián)學(xué)位表")brief = models.TextField(verbose_name="課程概述", max_length=2048)level_choices = ((0, '初級(jí)'), (1, '中級(jí)'), (2, '高級(jí)'))level = models.SmallIntegerField(choices=level_choices, default=1)pub_date = models.DateField(verbose_name="發(fā)布日期", blank=True, null=True)period = models.PositiveIntegerField(verbose_name="建議學(xué)習(xí)周期(days)", default=7) # order = models.IntegerField("課程順序", help_text="從上一個(gè)課程數(shù)字往后排")attachment_path = models.CharField(max_length=128, verbose_name="課件路徑", blank=True, null=True)status_choices = ((0, '上線'), (1, '下線'), (2, '預(yù)上線'))status = models.SmallIntegerField(choices=status_choices, default=0)template_id = models.SmallIntegerField("前端模板id", default=1)coupon = GenericRelation("Coupon")# 用于GenericForeignKey反向查詢,不會(huì)生成表字段,切勿刪除price_policy = GenericRelation("PricePolicy")asked_question = GenericRelation("OftenAskedQuestion")def __str__(self):return "%s(%s)" % (self.name, self.get_course_type_display())def save(self, *args, **kwargs):if self.course_type == 2:if not self.degree_course:raise ValueError("學(xué)位課程必須關(guān)聯(lián)對(duì)應(yīng)的學(xué)位表")super(Course, self).save(*args, **kwargs)class Meta:verbose_name_plural = "06.專題課或?qū)W位課模塊"class CourseDetail(models.Model):"""課程詳情頁內(nèi)容"""course = models.OneToOneField("Course")hours = models.IntegerField("課時(shí)")course_slogan = models.CharField(max_length=125, blank=True, null=True)video_brief_link = models.CharField(verbose_name='課程介紹', max_length=255, blank=True, null=True)why_study = models.TextField(verbose_name="為什么學(xué)習(xí)這門課程")what_to_study_brief = models.TextField(verbose_name="我將學(xué)到哪些內(nèi)容")career_improvement = models.TextField(verbose_name="此項(xiàng)目如何有助于我的職業(yè)生涯")prerequisite = models.TextField(verbose_name="課程先修要求", max_length=1024)recommend_courses = models.ManyToManyField("Course", related_name="recommend_by", blank=True)teachers = models.ManyToManyField("Teacher", verbose_name="課程講師")def __str__(self):return "%s" % self.courseclass Meta:verbose_name_plural = "07.課程或?qū)W位模塊詳細(xì)"class OftenAskedQuestion(models.Model):"""常見問題"""content_type = models.ForeignKey(ContentType) # 關(guān)聯(lián)course or degree_courseobject_id = models.PositiveIntegerField()content_object = GenericForeignKey('content_type', 'object_id')question = models.CharField(max_length=255)answer = models.TextField(max_length=1024)def __str__(self):return "%s-%s" % (self.content_object, self.question)class Meta:unique_together = ('content_type', 'object_id', 'question')verbose_name_plural = "08. 常見問題"class CourseOutline(models.Model):"""課程大綱"""course_detail = models.ForeignKey("CourseDetail")title = models.CharField(max_length=128)# 前端顯示順序order = models.PositiveSmallIntegerField(default=1)content = models.TextField("內(nèi)容", max_length=2048)def __str__(self):return "%s" % self.titleclass Meta:unique_together = ('course_detail', 'title')verbose_name_plural = "09. 課程大綱"class CourseChapter(models.Model):"""課程章節(jié)"""course = models.ForeignKey("Course")chapter = models.SmallIntegerField(verbose_name="第幾章", default=1)name = models.CharField(max_length=128)summary = models.TextField(verbose_name="章節(jié)介紹", blank=True, null=True)pub_date = models.DateField(verbose_name="發(fā)布日期", auto_now_add=True)class Meta:unique_together = ("course", 'chapter')verbose_name_plural = "10. 課程章節(jié)"def __str__(self):return "%s:(第%s章)%s" % (self.course, self.chapter, self.name)class CourseSection(models.Model):"""課時(shí)目錄"""chapter = models.ForeignKey("CourseChapter")name = models.CharField(max_length=128)order = models.PositiveSmallIntegerField(verbose_name="課時(shí)排序", help_text="建議每個(gè)課時(shí)之間空1至2個(gè)值,以備后續(xù)插入課時(shí)")section_type_choices = ((0, '文檔'), (1, '練習(xí)'), (2, '視頻'))section_type = models.SmallIntegerField(default=2, choices=section_type_choices)section_link = models.CharField(max_length=255, blank=True, null=True, help_text="若是video,填vid,若是文檔,填link")video_time = models.CharField(verbose_name="視頻時(shí)長(zhǎng)", blank=True, null=True, max_length=32) # 僅在前端展示使用pub_date = models.DateTimeField(verbose_name="發(fā)布時(shí)間", auto_now_add=True)free_trail = models.BooleanField("是否可試看", default=False)class Meta:unique_together = ('chapter', 'section_link')verbose_name_plural = "11. 課時(shí)"def __str__(self):return "%s-%s" % (self.chapter, self.name)class Homework(models.Model):chapter = models.ForeignKey("CourseChapter")title = models.CharField(max_length=128, verbose_name="作業(yè)題目")order = models.PositiveSmallIntegerField("作業(yè)順序", help_text="同一課程的每個(gè)作業(yè)之前的order值間隔1-2個(gè)數(shù)")homework_type_choices = ((0, '作業(yè)'), (1, '模塊通關(guān)考核'))homework_type = models.SmallIntegerField(choices=homework_type_choices, default=0)requirement = models.TextField(max_length=1024, verbose_name="作業(yè)需求")threshold = models.TextField(max_length=1024, verbose_name="踩分點(diǎn)")recommend_period = models.PositiveSmallIntegerField("推薦完成周期(天)", default=7)scholarship_value = models.PositiveSmallIntegerField("為該作業(yè)分配的獎(jiǎng)學(xué)金(貝里)")note = models.TextField(blank=True, null=True)enabled = models.BooleanField(default=True, help_text="本作業(yè)如果后期不需要了,不想讓學(xué)員看到,可以設(shè)置為False")class Meta:unique_together = ("chapter", "title")verbose_name_plural = "12. 章節(jié)作業(yè)"def __str__(self):return "%s - %s" % (self.chapter, self.title)# class CourseReview(models.Model): # """課程評(píng)價(jià)""" # enrolled_course = models.OneToOneField("EnrolledCourse") # about_teacher = models.FloatField(default=0, verbose_name="講師講解是否清晰") # about_video = models.FloatField(default=0, verbose_name="內(nèi)容實(shí)用") # about_course = models.FloatField(default=0, verbose_name="課程內(nèi)容通俗易懂") # review = models.TextField(max_length=1024, verbose_name="評(píng)價(jià)") # disagree_number = models.IntegerField(default=0, verbose_name="踩") # agree_number = models.IntegerField(default=0, verbose_name="贊同數(shù)") # tags = models.ManyToManyField("Tags", blank=True, verbose_name="標(biāo)簽") # date = models.DateTimeField(auto_now_add=True, verbose_name="評(píng)價(jià)日期") # is_recommend = models.BooleanField("熱評(píng)推薦", default=False) # hide = models.BooleanField("不在前端頁面顯示此條評(píng)價(jià)", default=False) # # def __str__(self): # return "%s-%s" % (self.enrolled_course.course, self.review) # # class Meta: # verbose_name_plural = "13. 課程評(píng)價(jià)(購買課程后才能評(píng)價(jià))" # # # class DegreeCourseReview(models.Model): # """學(xué)位課程評(píng)價(jià) # 為了以后可以定制單獨(dú)的評(píng)價(jià)內(nèi)容,所以不與普通課程的評(píng)價(jià)混在一起,單獨(dú)建表 # """ # enrolled_course = models.ForeignKey("EnrolledDegreeCourse") # course = models.ForeignKey("Course", verbose_name="評(píng)價(jià)學(xué)位模塊", blank=True, null=True, # help_text="不填寫即代表評(píng)價(jià)整個(gè)學(xué)位課程", limit_choices_to={'course_type': 2}) # about_teacher = models.FloatField(default=0, verbose_name="講師講解是否清晰") # about_video = models.FloatField(default=0, verbose_name="視頻質(zhì)量") # about_course = models.FloatField(default=0, verbose_name="課程") # review = models.TextField(max_length=1024, verbose_name="評(píng)價(jià)") # disagree_number = models.IntegerField(default=0, verbose_name="踩") # agree_number = models.IntegerField(default=0, verbose_name="贊同數(shù)") # tags = models.ManyToManyField("Tags", blank=True, verbose_name="標(biāo)簽") # date = models.DateTimeField(auto_now_add=True, verbose_name="評(píng)價(jià)日期") # is_recommend = models.BooleanField("熱評(píng)推薦", default=False) # hide = models.BooleanField("不在前端頁面顯示此條評(píng)價(jià)", default=False) # # def __str__(self): # return "%s-%s" % (self.enrolled_course, self.review) # # class Meta: # verbose_name_plural = "14. 學(xué)位課評(píng)價(jià)(購買課程后才能評(píng)價(jià))"class PricePolicy(models.Model):"""價(jià)格與有課程效期表"""content_type = models.ForeignKey(ContentType) # 關(guān)聯(lián)course or degree_courseobject_id = models.PositiveIntegerField()content_object = GenericForeignKey('content_type', 'object_id')# course = models.ForeignKey("Course")valid_period_choices = ((1, '1天'), (3, '3天'),(7, '1周'), (14, '2周'),(30, '1個(gè)月'),(60, '2個(gè)月'),(90, '3個(gè)月'),(180, '6個(gè)月'), (210, '12個(gè)月'),(540, '18個(gè)月'), (720, '24個(gè)月'),)valid_period = models.SmallIntegerField(choices=valid_period_choices)price = models.FloatField()class Meta:unique_together = ("content_type", 'object_id', "valid_period")verbose_name_plural = "15. 價(jià)格策略"def __str__(self):return "%s(%s)%s" % (self.content_object, self.get_valid_period_display(), self.price)# ################################### 優(yōu)惠券相關(guān) #################################class Coupon(models.Model):"""優(yōu)惠券生成規(guī)則"""name = models.CharField(max_length=64, verbose_name="活動(dòng)名稱")brief = models.TextField(blank=True, null=True, verbose_name="優(yōu)惠券介紹")coupon_type_choices = ((0, '立減'), (1, '滿減券'), (2, '折扣券'))coupon_type = models.SmallIntegerField(choices=coupon_type_choices, default=0, verbose_name="券類型")money_equivalent_value = models.IntegerField(verbose_name="等值貨幣")off_percent = models.PositiveSmallIntegerField("折扣百分比", help_text="只針對(duì)折扣券,例7.9折,寫79", blank=True, null=True)minimum_consume = models.PositiveIntegerField("最低消費(fèi)", default=0, help_text="僅在滿減券時(shí)填寫此字段")content_type = models.ForeignKey(ContentType, blank=True, null=True)object_id = models.PositiveIntegerField("綁定課程", blank=True, null=True, help_text="可以把優(yōu)惠券跟課程綁定")content_object = GenericForeignKey('content_type', 'object_id')quantity = models.PositiveIntegerField("數(shù)量(張)", default=1)open_date = models.DateField("優(yōu)惠券領(lǐng)取開始時(shí)間")close_date = models.DateField("優(yōu)惠券領(lǐng)取結(jié)束時(shí)間")valid_begin_date = models.DateField(verbose_name="有效期開始時(shí)間", blank=True, null=True)valid_end_date = models.DateField(verbose_name="有效結(jié)束時(shí)間", blank=True, null=True)# coupon_valid_days = models.PositiveIntegerField(verbose_name="優(yōu)惠券有效期(天)", blank=True, null=True,# help_text="自券被領(lǐng)時(shí)開始算起")date = models.DateTimeField(auto_now_add=True)class Meta:verbose_name_plural = "31. 優(yōu)惠券生成記錄"def __str__(self):return "%s(%s)" % (self.get_coupon_type_display(), self.name)class CouponRecord(models.Model):"""優(yōu)惠券發(fā)放、消費(fèi)紀(jì)錄"""coupon = models.ForeignKey("Coupon")account = models.ForeignKey("Account", verbose_name="擁有者")number = models.CharField(max_length=64, unique=True)status_choices = ((0, '未使用'), (1, '已使用'), (2, '已過期'))status = models.SmallIntegerField(choices=status_choices, default=0)get_time = models.DateTimeField(verbose_name="領(lǐng)取時(shí)間", help_text="用戶領(lǐng)取時(shí)間")used_time = models.DateTimeField(blank=True, null=True, verbose_name="使用時(shí)間")# order = models.ForeignKey("Order", blank=True, null=True, verbose_name="關(guān)聯(lián)訂單") # 一個(gè)訂單可以有多個(gè)優(yōu)惠券order_id = models.IntegerField(verbose_name='關(guān)聯(lián)訂單ID')class Meta:verbose_name_plural = "32. 用戶優(yōu)惠券"def __str__(self):return '%s-%s-%s' % (self.account, self.number, self.status)class Account(models.Model):username = models.CharField("用戶名", max_length=64, unique=True)email = models.EmailField(verbose_name='郵箱',max_length=255,unique=True,blank=True,null=True)password = models.CharField('密碼', max_length=128)class Meta:verbose_name_plural = "33. 用戶表" View Code?執(zhí)行2個(gè)命令,生成表
python manage.py makemigrations python manage.py migrate錄入幾條數(shù)據(jù)
?
作業(yè)
考試題(Python基礎(chǔ))
1. 寫代碼實(shí)現(xiàn):val = "i am a string",實(shí)現(xiàn)?個(gè)?法,將字符串逆序輸出(2分)
val = "i am a string" def func(st):return st[::-1]print(func(val)) View Code執(zhí)行輸出:?gnirts a ma i
?
2. 判斷101-200之間有多少個(gè)質(zhì)數(shù)(2分)
提示:?個(gè)?于1的?然數(shù),除了1和它?身外,不能被其他?然數(shù)整除的書叫質(zhì)數(shù) 循環(huán)加判斷,取余數(shù)為0
執(zhí)行輸出:
[101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199] View Code?
3. 簡(jiǎn)述正則表達(dá)式中的貪婪匹配并舉例說明(2分)
貪婪匹配:正則表達(dá)式一般趨向于最大長(zhǎng)度匹配,也就是所謂的貪婪匹配。如下面使用模式p匹配字符串str,結(jié)果就是匹配到:abcaxc(ab*c)。 如:String str="abcaxc";Patter p="ab*c"; View Code?
4. 寫代碼(3分)
v1 = {11,22,33}
v2 = {22,44,55}
a. 如何獲取 v1 中存在?v2中不存在的值?
b. 如何獲取 v2 中存在?v2中不存在的值?
c. 如何獲取v1和v2中都存在的值?
print(v1-v2) # 差集 print(v2-v1) # 差集 print(v1.intersection(v2)) # 交集 View Code?
5. 請(qǐng)編寫?個(gè)函數(shù)實(shí)現(xiàn)將IP地址轉(zhuǎn)換成?個(gè)整數(shù)(4分)
如 10.3.9.12 轉(zhuǎn)換規(guī)則為: 10 00001010 3 00000011 9 00001001 12 00001100 再將以上?進(jìn)制拼接起來計(jì)算?進(jìn)制結(jié)果,即: 00001010 00000011 00001001 00001100 = ?
執(zhí)行輸出:33554688
?
ORM查詢
獲取用戶ID=1的所有優(yōu)惠券
obj = models.Account.objects.filter(id=1).first()for i in obj.couponrecord_set.all():print(i.coupon.id,i.coupon.get_coupon_type_display(),i.coupon.off_percent) View Code?
獲取專題課ID=1且用戶ID=10的所有優(yōu)惠券
obj1 = models.Course.objects.filter(id=1).first()print(obj1.coupon.all())for i in obj1.coupon.all():print(i) View Code?
獲取用戶ID=10的所有未綁定課程的優(yōu)惠券
obj2 = models.CouponRecord.objects.filter(account=1,coupon__object_id__isnull=False)for i in obj2:print(i.coupon.id,i.coupon.get_coupon_type_display(),i.coupon.off_percent) View Code?
獲取用戶ID=1的所有可用優(yōu)惠券
?
posted @ 2018-08-13 16:48 肖祥 閱讀(...) 評(píng)論(...) 編輯 收藏總結(jié)
以上是生活随笔為你收集整理的python 全栈开发,Day103(微信消息推送,结算中心业务流程)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三相全控tc787触发电路_三相桥式全控
- 下一篇: 手机html轮播图,jquery支持移动