1. 程式人生 > 其它 >grpc Go gRPC使用demo

grpc Go gRPC使用demo

目錄

一、純手擼web框架

1.web框架的本質
	理解1:連線前端與資料庫的中間介質
	理解2:socket服務端
2.手寫web框架
	1.編寫socket服務端程式碼
 	2.瀏覽器訪問響應無效>>>:HTTP協議
 	3.根據網址字尾的不同獲取不同的頁面內容
	4.想辦法獲取到使用者輸入的字尾>>>:請求資料
 	5.請求首行
    	GET /login HTTP/1.1
 		GET請求
        朝別人索要資料
  		POST請求
        朝別人提交資料
 	6.處理請求資料獲取網址字尾
"""
1.socket程式碼過於重複
2.針對請求資料處理繁瑣
3.字尾匹配邏輯過於LowB
"""
import socket


server = socket.socket()  # TCP UDP
server.bind(('127.0.0.1', 8080))  # IP PORT
server.listen(5)  # 半連線池


while True:
    sock, address = server.accept()  # 等待連線
    data = sock.recv(1024)  # 位元組(bytes)
    # print(data.decode('utf8'))  # 解碼列印
    sock.send(b'HTTP/1.1 200 OK\r\n\r\n')
    data_str = data.decode('utf8')  # 先轉換成字串
    target_url = data_str.split(' ')[1]  # 按照空格切割字串並取索引1對應的資料
    # print(target_url)  # /index /login /reg
    if target_url == '/index':
        # sock.send(b'index page')
        with open(r'myhtml01.html','rb') as f:
            sock.send(f.read())
    elif target_url == '/login':
        sock.send(b'login page')
    else:
        sock.send(b'home page!')

二、基於wsgiref模組

內建模組 很多web框架底層使用的模組
	功能1:封裝了socket程式碼
 	功能2:處理了請求資料
1.固定程式碼啟動服務端
2.檢視處理之後的request大字典
3.根據不同的網址字尾返回不同的內容>>>:研究大字典鍵值對
4.立刻解決上述純手擼的兩個問題
5.針對最後一個問題程式碼如何優化

from wsgiref.simple_server import make_server


def run(request, response):
    """
    :param request: 請求相關資料
    :param response: 響應相關資料
    :return: 返回給客戶端的真實資料
    """
    response('200 OK', [])  # 固定格式 不用管它
    # print(request)  是一個處理之後的大字典
    path_info = request.get('PATH_INFO')
    if path_info == '/index':
        return [b'index']
    elif path_info == '/login':
        return [b'login']
    return [b'hello wsgiref module']


if __name__ == '__main__':
    server = make_server('127.0.0.1', 8080, run)  # 實時監聽127.0.0.1:8080 一旦有請求過來自動給第三個引數加括號並傳引數呼叫
    server.serve_forever()  # 啟動服務端

三、程式碼封裝優化

1.網址字尾的匹配問題
2.每個字尾匹配成功後執行的程式碼有多有少
	麵條版	函式版	模組版
3.將分支的程式碼封裝成一個個函式
4.將網址字尾與函式名做對應關係
5.獲取網址字尾迴圈匹配
6.如果想新增功能只需要先寫函式再新增一個對應關係即可
7.根據不同的功能拆分成不同的py檔案
	views.py		儲存核心業務邏輯(功能函式)
 	urls.py			儲存網址字尾與函式名對應關係
 	templates目錄	   儲存html頁面檔案
8.為了使函式體程式碼中業務邏輯有更多的資料可用
	將request大字典轉手傳給這個函式(可用不用但是不能沒有)

四、動靜態網頁

動態網頁
	頁面資料來源於後端
靜態網頁
	頁面資料直接寫死
    
1.訪問某個網址字尾 後端程式碼獲取當前時間 並將該時間傳到html檔案上再返回給瀏覽器展示給使用者看
	讀取html內容(字串型別) 然後利用字串替換 最後再返回給瀏覽器
    
2.將字典傳遞給頁面內容 並且在頁面上還可以通過類似於後端的操作方式操作該資料
	模板語法>>>:jinja2模組

五、jinja2模組

pip3 install jinja2


from jinja2 import Template


def get_dict_func(request):
    user_dict = {'name': 'jason', 'age': 18, 'person_list': ['阿珍', '阿強', '阿香', '阿紅']}
    with open(r'templates/get_dict_page.html', 'r', encoding='utf8') as f:
        data = f.read()
    temp_obj = Template(data)  # 將頁面資料交給模板處理
    res = temp_obj.render({'d1': user_dict})  # 給頁面傳了一個 變數名是d1值是字典資料的資料
    return res

<p>{{ d1 }}</p>
<p>{{ d1.name }}</p>
<p>{{ d1['age'] }}</p>
<p>{{ d1.get('person_list') }}</p>

六、前端、後端、資料庫三者聯動

1.前端瀏覽器訪問get_user 後端連線資料庫查詢use表中所有的資料 傳遞到某個html頁面 弄弄好樣式 再發送給瀏覽器展示

{% for user_dict in user_data_list %}
    <tr>
        <td>{{ user_dict.id }}</td>
        <td>{{ user_dict.name }}</td>
        <td>{{ user_dict.age }}</td>
    </tr>
{% endfor %}

七、python主流web框架

ps:作為小白的你,初學階段不要混著學,很容易走火入魔,先學Django就好了。

1.django
	大而全 自身自帶的功能元件非常的多 類似於航空母艦 		
2.flask
	小而精 自身自帶的功能元件非常的少 類似於遊騎兵
 	幾乎所有的功能都需要依賴於第三方模組 
3.tornado
	非同步非阻塞 速度極快效率極高甚至可以充當遊戲服務端
ps:sanic、fastapi...

八、django簡介

1.版本問題

  • django1.X:同步 1.11
  • django2.X:同步 2.2
  • django3.X:支援非同步 3.2
  • django4.X:支援非同步 4.2

ps:版本之間的差異其實不大 主要是添加了額外的功能

通常來說我們使用的都是上圖中的LTS版本的Django,一些老專案會使用1.11版本,我們學習的是2.2.22版本。

2.執行django注意事項

1.django專案中所有的檔名目錄名不要出現中文
2.計算機名稱儘量也不要出現中文
3.一個pycharm儘量就是一個完整的專案(不要巢狀 不要疊加)
4.不同版本的python直譯器與不同版本的django可能會出現小問題(這裡依舊是百度解決問題,身邊有大佬也可以求助大佬)

九、django基本使用

1.下載模組

pip方式下載

	pip3 install django 				預設最新版
 	pip3 install django==版本號		  指定版本
    pip3 install django==2.2.22

pycharm中下載

依舊是點選左上角的File,然後選擇settings

在出現的彈窗中點選左邊的project選項然後選擇interpreter

在右邊出現如圖視窗後,在右側視窗中雙擊,然後再在出現的視窗中搜索Django

待載入完成後我們選擇Django模組,然後在右側下方勾選Specify version,然後再在這裡選擇需要安裝的版本

再點選install即可

特殊情況說明

當我們在pycharm中下載的時候會出現提示,告訴我們在安裝的時候出現了關聯安裝(即順帶安裝了一些關聯的模組)。

但是在cmd中用pip下載模組,會自動解決依賴問題(不會把關聯需要用到的模組一起下了)。

2.驗證

cmd視窗直接輸入django-admin有一長串結果展示表明成功(需提前配置直譯器環境變數)

django-admin

3.常見命令

1、建立django專案

django-admin startproject 專案名(如:mysite)

2、啟動django專案

ps:需要先進入專案的所在目錄才能使用程式碼啟動Django服務

    cd 專案名(如:mysite)
    python3 manage.py runserver IP:PORT 

IP:PORT可以不寫 預設在本地8000埠起服務
如果想使用本地地址,使用的ip是127.0.0.1
如果想要使用本機ip,需要在settings.py檔案中修改配置

ALLOWED_HOSTS = []

預設這個列表是空的(也就是隻允許本機訪問)

ALLOWED_HOSTS = []

修改這個列表:

ALLOWED_HOSTS = ['*'] # 允許所有的主機

當然也可以指定可訪問主機的ip:

ALLOWED_HOSTS = ['198.211.99.20', 'localhost', '127.0.0.1']

3、建立app應用

python3 manage.py startapp 應用名(jason01)

4.pycharm自動建立django專案

  • templates資料夾是用於存放html檔案的。

  • pycharm會自動建立templates資料夾,但是配置檔案中可能會報錯,需要我們手動修改。在cmd中需要自己建立,並開啟檔案新增配置資訊

這裡是我們在pycharm中建的Django專案,專案內部的settings.py檔案會有錯誤,需要我們手動修改

把中括號以及內部的資訊替換成下列程式碼即可(cmd中建立的Django專案,如果也用templates當作資料夾的名稱,也是新增一樣的程式碼)。

[os.path.join(BASE_DIR,'templates'),]

十、django app(應用)的概念

概念

  • app全程為application

  • django類似於是一所大學 app(應用)類似於大學裡面的各個學院

  • 大學相當於是個空殼子(負責提供環境,類似Django)

  • 學院才是一個個真正具備特定功能的集合(即內部的一個個app)

eg:

	我們使用django寫一個淘寶,淘寶裡面有很多功能模組
	我們應該先建立一個空的django專案然後根據功能的不同建立不同的應用
django專案
	應用名01(user)      使用者相關業務
	應用名02(order)    訂單相關業務
	應用名03(goods)     產品相關業務
	應用名04(backend)        後臺相關業務

命令列建立應用

python38 manage.py startapp 應用名

pycharm建立應用

新建django專案可以預設建立一個 並且自動註冊

其次我們也可以在pycharm中開啟終端用命令列的指令建立應用

同時在pycharm中也有一個經過優化的終端,在內部輸入指令可以簡化輸入。

建立應用注意事項

建立的app一定要去settings.py中註冊,註冊資訊格式如下:

app01是配置資訊的全寫,app02是配置資訊的縮寫。

INSTALLED_APPS = [
    	'app01.apps.App01Config',
		'app02'
	]

十一、django主要目錄結構

django專案目錄名
	django專案同名目錄
    	settings.py		 專案配置檔案
    	urls.py			儲存網址字尾與函式名對應關係(不嚴謹,專業叫法為總路由層)
   		wsgi.py			wsgiref閘道器檔案
	db.sqlite3檔案	   django自帶的小型資料庫(專案啟動之後才會出現)
	manage.py			 入口檔案(命令提供)
 	應用目錄(應用的資料夾) 通過命令建立(可以建立任意個數)
    	migrations目錄	儲存資料庫相關記錄
    	admin.py		 django內建的admin後臺管理功能
        apps.py			註冊app相關(用於配置檔案的應用註冊(建立的應用都需要去配置檔案中註冊))
   		models.py		 與資料庫打交道的(非常重要,專業稱呼為模型層)
    	tests.py		 自帶的測試檔案
    	views.py		 儲存功能函式(不嚴謹,專業稱呼為檢視層(編寫當前應用核心業務邏輯程式碼))
   	templates目錄			儲存html檔案(命令列不會自動建立 pycharm會)
    	配置檔案中還需要配置路徑
        	
 
"""
	網址字尾			 路由
	函式				  檢視函式
	類				   檢視類
重要名詞講解
	urls.py				 路由層	
	views.py			 檢視層
	models.py			 模型層
	templates			 模板層
"""

十二、django小白必會三板斧

從Django模組中匯入的這三個小模組合在一起稱為三板斧

from django.shortcuts import render,HttpResponse,redirect

HttpResponse		 返回字串型別的資料

render				返回html頁面並且支援傳值

redirect			重定向

十三、靜態檔案

比如我們要建立一個使用者登陸頁面,這時候就需要建立一個html檔案同時引入一些配置檔案。

1.靜態檔案概念

  • 靜態檔案指的是不怎麼經常變化的檔案,主要針對html檔案所使用的到的各種資源

      如:css檔案、js檔案、img檔案、第三方框架檔案
    
  • django針對靜態檔案資源需要單獨開始一個目錄統一存放

      目錄名稱:static目錄
      
      該目錄下如果各種型別的檔案都多,還可以繼續建立目錄
      
      			css目錄(存放css的檔案)
      
      			js目錄(存放js的檔案)
      
      			img目錄(存放圖片)
      
      			存放外掛:utils目錄/plugins目錄/libs目錄/others目錄/或是不創
    

2.資源訪問

我們在位址列中之所以可以屬於路由獲取到相應的資源是因為程式設計師提前開設了資源的介面

3.靜態檔案資源訪問

預設情況下無法訪問,因為我們沒有提前開設靜態檔案資源的訪問介面,也就是前端不能直接訪問後端的檔案。

十四、靜態檔案相關配置

想讓前端能訪問後端的檔案需要設定配置資訊開放許可權。
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

ps:名稱需要純大寫,否則不會執行

1.介面字首

STATIC_URL = '/xxx/'  
# 訪問靜態檔案資源的介面字首(相當於通行證)
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),  # 儲存靜態檔案資源的目錄名稱
    os.path.join(BASE_DIR, 'static1'),  # 儲存靜態檔案資源的目錄名稱,可以同時建立多個目錄
    os.path.join(BASE_DIR, 'static2'),  # 儲存靜態檔案資源的目錄名稱
]
介面字首正確之後 會拿著後面的路徑依次去到列表中自上而下查詢,一旦找到就返回

2.介面字首動態匹配

當我們在配置檔案中開放了介面後,如果我們想要修改介面名稱就需要在html檔案中同時進行修改,當網頁很多的時候工作量就會很大,這時候就需要設定介面字首的動態匹配。
<head>
    <meta charset="UTF-8">
    <title>blogs</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'blog.css' %}">
    <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</head>

十五、form表單

action屬性

我們給表單標籤form新增屬性action控制資料提交的地址

<form action="/login/" method="post">

action屬性的三種配置

	1.action=""  資料預設提交給當前頁面所在的地址
	2.action="https://www.baidu.com/"  完整地址
 	3.action="/index/"  朝當前服務端的index地址提交

method屬性

<form action="/login/" method="post">

在http協議中瀏覽器和服務端通過報文互動,報文分成請求報文和響應報文,轉換到method屬性中就是get和post兩種值。

作用:控制資料提交的方法

	預設情況是get
	可以改post

請求方法補充

get

  • 朝服務端索要資料 也可以攜帶一些額外的要求

      攜帶額外資料的方式:  URL?xxx=yyy&uuu=zzz
    
      也就是說網址後面用?隔開資料,資料之間用&符號分隔
    
      問號後面攜帶資料的大小是有限制(2KB)的並且不能攜帶敏感資料
    
  • 當我們開啟瀏覽器訪問網頁的時候就是get方式

post

  • 朝服務端提交資料

      攜帶額外資料的方式:  請求體
    
      請求體攜帶資料安全性較高並且沒有大小限制
    
  • 當我們使用按鈕提交新資料的時候使用的就是post方式

前期傳送post請求需要註釋掉配置檔案中的某一行(後面還會講的)

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

十六、request物件

這裡介紹了request物件的一些方法

request.method	獲取請求方式 結果是純大寫的字串資料
	結果:GET\POST
    
request.POST	獲取post請求請求體裡面攜帶的資料
	request.POST.get()		獲取列表最後一個數據值
 	request.POST.getlist()	 獲取整個列表資料,獲取了列表後可以使用索引獲取列表中的值
    
request.GET		獲取網址問號後面攜帶的資料
	request.GET.get()		獲取列表最後一個數據值
 	request.GET.getlist()	 獲取整個列表資料,跟POST一樣,獲取了列表後可以使用索引獲取列表中的值
 
"""
在檢視函式中針對不同的請求程式碼編寫套路
	if request.method == 'POST':
		return HttpResponse()
	return HttpResponse()
"""

十七、django連線資料庫

django自帶的sqlite3是一個小型的資料庫 功能比較少 主要用於本地測試
我們實際專案中都會替換掉它

預設配置sqlite3

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

我們在學習過程中使用mysqlclient模組替換預設的資料庫

1.需要指定模組

	django1.X版本需要在專案目錄下或者app目錄下的__init__.py編寫程式碼
    	import pymysql
    	pymysql.install_as_MySQLdb()
	django2.X及以上都可以直接通過下載mysqlclient模組解決
    	pip3.8 install mysqlclient
        或是pycharm中下載

ps:該模組windows下載問題不大 主要是mac電腦可能有問題

2.修改配置檔案

DATABASES = {
    'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'day51',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'USER': 'root',
            'PASSWORD': '123',
            'CHARSET': 'utf8'
        }
}

app檔案目錄中的雙下init檔案也需要新增配置

import pymysql
pymysql.install_as_MySQLdb()

十八、pycharm連線MySQL資料庫

方式一:

在pycharm右上角點選圖示後建立連線

之後彈出一個彈窗,輸入資料庫的資訊

第一次連線的時候會要求下載外掛,這裡點選下載就好了,很快的

接著點選下方的Test Connection測試連線,成功了就可以點選ok儲存退出了

方式二:

使用左下角的圖示連線資料庫


後續操作參考方法一

十九、ORM簡介

1、ORM概念

物件關係對映(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向物件與關係資料庫存在的互不匹配的現象的技術。

簡單的說,ORM是通過使用描述物件和資料庫之間對映的元資料,將程式中的物件自動持久化到關係資料庫中。因此實現了讓不會SQL語句的python程式設計師,使用python面向物件的語法來操作資料庫的目的。

ORM在業務邏輯層和資料庫層之間充當了橋樑的作用。

類				    表
物件				   一條條資料
物件點名字			 資料獲取欄位對應的值

ps:ORM由於高度封裝了SQL,所以有時候效率較低,我們需要自己寫SQL。

2、ORM由來

讓我們從O/R開始。字母O起源於"物件"(Object),而R則來自於"關係"(Relational)。

幾乎所有的軟體開發過程中都會涉及到物件和關係資料庫。在使用者層面和業務邏輯層面,我們是面向物件的。當物件的資訊發生變化的時候,我們就需要把物件的資訊儲存在關係資料庫中。

按照之前的方式來進行開發就會出現程式設計師會在自己的業務邏輯程式碼中夾雜很多SQL語句用來增加、讀取、修改、刪除相關資料,而這些程式碼通常都是重複的。

3、ORM的優勢和劣勢

ORM的優勢

ORM解決的主要問題是物件和關係的對映。它通常把一個類和一個表一一對應,類的每個例項對應表中的一條記錄,類的每個屬性對應表中的每個欄位。

ORM提供了對資料庫的對映,不用直接編寫SQL程式碼,只需像操作物件一樣從資料庫操作資料。

讓軟體開發人員專注於業務邏輯的處理,提高了開發效率。

ORM的劣勢

ORM的缺點是會在一定程度上犧牲程式的執行效率。

ORM用多了SQL語句就不會寫了,關係資料庫相關技能退化…

二十、ORM基本操作

因為ORM相當於是對資料庫進行對映操作,所以我們需要跟資料庫中的表建立關係

1.現在app中的models.py中編寫模型類

	class GirlsInfo(models.Model):
        # 欄位名 = 欄位型別 + 約束條件
        id = models.AutoField(primary_key=True)  
        name = models.CharField(max_length=32)
        age = models.IntegerField()

2.執行資料庫遷移相關命令

	python38 manage.py makemigrations  將操作記錄到小本本上(migrations)
    執行成功後migrations資料夾下會多出一個py檔案
	python38 manage.py migrate		  將操作同步到資料庫上
'''注意每次在models.py修改了與資料庫相關的程式碼 都需要再次執行上述命令'''

如果出現下方問題

解決方案是修改配置檔案

成功的結果如下圖

二十一、ORM基本語句

from app01 import models
models.類名.objects.create()		建立記錄
models.UserInfor.objects.create(name='zzh',pwd='123')

models.類名.objects.filter()		檢視記錄
res = models.UserInfor.objects.filter(name=name)
print(res)
print(res[0])
print(res[0].id)
print(res[0].name)
print(res[0].pwd)

models.類名.objects.update()		修改記錄
models.UserInfor.objects.filter(id=2).update(name='xiaozhu',pwd='666')

models.類名.objects.delete()		刪除記錄
models.UserInfor.objects.filter(id=2).delete()