telepath是一個Django庫,用於在Python和JavaScript之間交換數據,使您可以建立具有豐富客戶端介面的應用程序,同時將業務邏輯保留在伺服器端程式碼中。
它有什麼作用?
它提供了一個將包括Python物件在內的結構化資料打包為JSON可序列化格式的機制。透過向對應的JavaScript實作註冊該機制,可以擴展該機制以支援任何Python類別。然後,打包的資料可以包含在HTTP回應中,並在JavaScript中解壓縮以獲得與原始資料等效的資料結構。
安裝方法
pip install telepath
並將'telepath'新增至專案的INSTALLED_APPS。
簡介
假設我們正在建立一個用於玩跳棋的Django應用程式。我們已經花了數天或數週的時間,建構了遊戲規則的Python實現,並提供了代表當前遊戲狀態和各個部分的類別。但是,我們也希望為播放器提供一個適當且友善的使用者介面,這意味著該是我們編寫JavaScript前端的時候了。我們的UI程式碼不可避免地將擁有自己的對象,這些對象代表不同的角色,鏡像我們正在伺服器上追蹤的資料結構——但我們無法發送Python對象,因此將這些資料傳送到客戶端通常將意味著設計遊戲狀態的JSON表示形式,並在兩端分別設計大量樣式程式碼,遍歷資料結構以在本機物件之間來回轉換。讓我們看看telepath如何簡化這個過程。
一個完整的跳棋遊戲對於本教學來說有點太多了,所以我們只選擇渲染這一步...
在Python環境中,創建一個新的Django專案:
pip install "Django>=3.1,<p>在draughts / settings.py的INSTALLED_APPS清單中加入'games'。 </p><p>為簡單起見,在本範例中,我們將不涉及資料庫,而是將遊戲狀態表示為普通的Python類別而不是Django模型。修改games/views.py,如下所示:</p><pre class="brush:php;toolbar:false">from django.shortcuts import render class Piece: def __init__(self, color, position): self.color = color self.position = position class GameState: def __init__(self, pieces): self.pieces = pieces @staticmethod def new_game(): black_pieces = [ Piece('black', (x, y)) for y in range(0, 3) for x in range((y + 1) % 2, 8, 2) ] white_pieces = [ Piece('white', (x, y)) for y in range(5, 8) for x in range((y + 1) % 2, 8, 2) ] return GameState(black_pieces + white_pieces) def game(request): game_state = GameState.new_game() return render(request, 'game.html', {})
如下所示建立games/templates/game.html:
nbsp;html> <title>Draughts</title> <script> document.addEventListener('DOMContentLoaded', event => { const gameElement = document.getElementById('game'); gameElement.innerHTML = 'TODO: render the board here' }); </script> <h2 id="Draughts">Draughts</h2> <div> </div>
將新視圖新增至draughts/urls.py:
from django.contrib import admin from django.urls import path from games.views import game urlpatterns = [ path('', game), path('admin/', admin.site.urls), ]
現在,使用./manage.py runserver啟動伺服器,並造訪http:// localhost:8000 /。
到目前為止,我們已經創建了一個代表新遊戲的GameState物件——現在是時候引入telepath,以便我們可以將該物件傳輸到客戶端。執行下方指令:
pip install telepath
並將'telepath'加入draughts / settings.py中的INSTALLED_APPS清單中。現在編輯games/views.py檔案:
import json from django.shortcuts import render from telepath import JSContext # ... def game(request): game_state = GameState.new_game() js_context = JSContext() packed_game_state = js_context.pack(game_state) game_state_json = json.dumps(packed_game_state) return render(request, 'game.html', { 'game_state_json': game_state_json, })
這裡JSContext是一個幫助工具,用於管理遊戲狀態物件到我們可以在Javascript中使用的表示形式的轉換。 js_context.pack接受該物件並將其轉換為可以JSON序列化並傳遞到我們的模板的值。但是,現在重新載入頁面失敗,並出現以下形式的錯誤:don't know how to pack object:
這是因為GameState是Telepath尚不知道如何處理的自訂Python類型。傳遞給pack的任何自訂類型必須連結到對應的JavaScript實作;這是透過定義Adapter物件並將其註冊到telepath來完成的。如下更新game / views.py:
import json from django.shortcuts import render from telepath import Adapter, JSContext, register # ... class GameState: # keep definition as before class GameStateAdapter(Adapter): js_constructor = 'draughts.GameState' def js_args(self, game_state): return [game_state.pieces] class Media: js = ['draughts.js'] register(GameStateAdapter(), GameState)
此處js_constructor是JavaScript建構子的標識符,該標識符將用於在客戶端上建立GameState實例,並且js_args定義了將傳遞給此構造函數的參數列表,以重新建立給定game_state物件的JavaScript對應物件 。 Media類別指示文件,該文件遵循Django對格式媒體的約定,可在其中找到GameState的JavaScript實作。稍後我們將看到此JavaScript實作的外觀,現在,我們需要為Piece類別定義一個類似的適配器,因為我們對GameStateAdapter的定義取決於是否能夠打包Piece實例。將以下定義新增至games/views.py:
class Piece: # keep definition as before class PieceAdapter(Adapter): js_constructor = 'draughts.Piece' def js_args(self, piece): return [piece.color, piece.position] class Media: js = ['draughts.js'] register(PieceAdapter(), Piece)
重新載入頁面,您將看到錯誤提示消失了,這表示我們已成功將GameState物件序列化為JSON並將其傳遞給範本。現在,我們可以將其包含在模板中-編輯games/templates/game.html:
<h2 id="Draughts">Draughts</h2> <div> </div>
再次重新載入頁面,並在瀏覽器的開發人員工具中檢查遊戲元素(在Chrome和Firefox中,右鍵點選TODO註釋,然後選擇Inspect或Inspect Element),您將看到GameState物件的JSON表示,準備好解壓成完整的JavaScript物件。
除了將資料打包成JSON可序列化的格式外,JSContext物件還追蹤將資料解壓縮所需的JavaScript媒體定義,作為其媒體屬性。讓我們更新遊戲視圖,以將其也傳遞給模板-在games/views.py中:
def game(request): game_state = GameState.new_game() js_context = JSContext() packed_game_state = js_context.pack(game_state) game_state_json = json.dumps(packed_game_state) return render(request, 'game.html', { 'game_state_json': game_state_json, 'media': js_context.media, })
將下面程式碼新增至games / templates / game.html中的HTML頭檔:
<title>Draughts</title> {{ media }} <script> document.addEventListener('DOMContentLoaded', event => { const gameElement = document.getElementById('game'); gameElement.innerHTML = 'TODO: render the board here' }); </script>
重新加载页面并查看源代码,您将看到这带来了两个JavaScript包括 —— telepath.js(客户端telepath库,提供解包机制)和我们在适配器定义中指定的draughts.js文件。后者尚不存在,所以让我们在games / static / draughts.js中创建它:
class Piece { constructor(color, position) { this.color = color; this.position = position; } } window.telepath.register('draughts.Piece', Piece); class GameState { constructor(pieces) { this.pieces = pieces; } } window.telepath.register('draughts.GameState', GameState);
这两个类定义实现了我们先前在适配器对象中声明的构造函数-构造函数接收的参数是js_args定义的参数。window.telepath.register行将这些类定义附加到通过js_constructor指定的相应标识符。现在,这为我们提供了解压缩JSON所需的一切-回到games / templates / game.html中,更新JS代码,如下所示:
<script> document.addEventListener('DOMContentLoaded', event => { const gameElement = document.getElementById('game'); const gameStateJson = gameElement.dataset.gameState; const packedGameState = JSON.parse(gameStateJson); const gameState = window.telepath.unpack(packedGameState); console.log(gameState); }) </script>
您可能需要重新启动服务器以获取新的games/static文件夹。重新加载页面,然后在浏览器控制台中,您现在应该看到填充了Piece对象的GameState对象。现在,我们可以继续在games/static/draughts.js中填写渲染代码:
class Piece { constructor(color, position) { this.color = color; this.position = position; } render(container) { const element = document.createElement('div'); container.appendChild(element); element.style.width = element.style.height = '24px'; element.style.border = '2px solid grey'; element.style.borderRadius = '14px'; element.style.backgroundColor = this.color; } } window.telepath.register('draughts.Piece', Piece) class GameState { constructor(pieces) { this.pieces = pieces; } render(container) { const table = document.createElement('table'); container.appendChild(table); const cells = []; for (let y = 0; y { const [x, y] = piece.position; const cell = cells[y][x]; piece.render(cell); }); } } window.telepath.register('draughts.GameState', GameState)
在games/templates/game.html中添加对render方法的调用:
<script> document.addEventListener('DOMContentLoaded', event => { const gameElement = document.getElementById('game'); const gameStateJson = gameElement.dataset.gameState; const packedGameState = JSON.parse(gameStateJson); const gameState = window.telepath.unpack(packedGameState); gameState.render(gameElement); }) </script>
重新加载页面,您将看到我们的跳棋程序已准备就绪,可以开始游戏了。
让我们快速回顾一下我们已经取得的成果:
我们已经打包和解包了自定义Python / JavaScript类型的数据结构,而无需编写代码来递归该结构。如果我们的GameState对象变得更复杂(例如,“棋子”列表可能变成棋子和国王对象的混合列表,或者状态可能包括游戏历史),则无需重构任何数据打包/拆包逻辑,除了为每个使用的类提供一个适配器对象。
仅提供了解压缩页面数据所需的JS文件-如果我们的游戏应用程序扩展到包括Chess,Go和Othello,并且所有生成的类都已通过Telepath注册,则我们仍然只需要提供与跳棋知识相关的代码。
即使我们使用任意对象,也不需要动态内联JavaScript —— 所有动态数据都以JSON形式传递,并且所有JavaScript代码在部署时都是固定的(如果我们的网站强制执行CSP,这一点很重要)。
以上是Python和JavaScript間交換資料的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于Seaborn的相关问题,包括了数据可视化处理的散点图、折线图、条形图等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于进程池与进程锁的相关问题,包括进程池的创建模块,进程池函数等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于简历筛选的相关问题,包括了定义 ReadDoc 类用以读取 word 文件以及定义 search_word 函数用以筛选的相关内容,下面一起来看一下,希望对大家有帮助。

VS Code的确是一款非常热门、有强大用户基础的一款开发工具。本文给大家介绍一下10款高效、好用的插件,能够让原本单薄的VS Code如虎添翼,开发效率顿时提升到一个新的阶段。

pythn的中文意思是巨蟒、蟒蛇。1989年圣诞节期间,Guido van Rossum在家闲的没事干,为了跟朋友庆祝圣诞节,决定发明一种全新的脚本语言。他很喜欢一个肥皂剧叫Monty Python,所以便把这门语言叫做python。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于数据类型之字符串、数字的相关问题,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于numpy模块的相关问题,Numpy是Numerical Python extensions的缩写,字面意思是Python数值计算扩展,下面一起来看一下,希望对大家有帮助。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載
最受歡迎的的開源編輯器