検索
ホームページバックエンド開発Python チュートリアルPython と JavaScript の間でデータを交換する方法

telepath は、Python と JavaScript の間でデータを交換するための Django ライブラリで、ビジネス ロジックをサーバー側コードに保持しながら、豊富なクライアント側インターフェイスを備えたアプリケーションを構築できます。

これは何をするものですか?

これは、Python オブジェクトを含む構造化データを JSON シリアル化可能な形式にパッケージ化するメカニズムを提供します。このメカニズムは、対応する JavaScript 実装に登録することで、任意の Python クラスをサポートするように拡張できます。パックされたデータは HTTP 応答に含められ、JavaScript で解凍されて、元のデータと同等のデータ構造を取得できます。

インストール方法

pip install telepath

そして、プロジェクトの INSTALLED_APPS に「telepath」を追加します。

はじめに

チェッカーをプレイするための Django アプリケーションを構築しているとします。私たちは数日から数週間をかけて、ゲーム ルールの Python 実装を構築し、現在のゲーム状態やさまざまな部分を表すクラスを提供しました。ただし、適切にユーザーフレンドリーなインターフェイスをプレーヤーに提供したいとも考えています。つまり、JavaScript フロントエンドを作成する時期が来たことを意味します。私たちの UI コードには、必然的にさまざまな役割を表す独自のオブジェクトが含まれ、サーバー上で追跡しているデータ構造をミラーリングします。ただし、Python オブジェクトを送信することはできないため、このデータをクライアントに送信することは通常、ゲーム状態の JSON 表現を設計することを意味します。 、そして両端で多くのスタイル コードを設計し、データ構造を走査してネイティブ オブジェクト間で相互に変換します。テレパスがどのようにプロセスを簡素化するかを見てみましょう。

完全なチェッカー ゲームはこのチュートリアルには少し多すぎるため、レンダリング ステップだけを選択します...

Python 環境で、新しい Django プロジェクトを作成します:

pip install "Django>=3.1,<p>drafts/settings.py の INSTALLED_APPS リストに「ゲーム」を追加します。 </p><p>わかりやすくするために、この例ではデータベースを使用せず、Django モデルではなく通常の Python クラスとしてゲームの状態を表します。 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(&#39;DOMContentLoaded&#39;, event => {                 const gameElement = document.getElementById(&#39;game&#39;);                 gameElement.innerHTML = &#39;TODO: render the board here&#39;             });         </script>                   <h2 id="Draughts">Draughts</h2>         <div>         </div>      

新しいビューをdrafts/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 オブジェクトを作成しました。今度は、そのオブジェクトをクライアントに転送できるようにテレパスを導入します。コマンド

pip install telepath

を実行し、drafts/settings.py の INSTALLED_APPS リストに「telepath」を追加します。ここで、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,     })

Here JSContext は、ゲーム状態オブジェクトの Javascript で使用できる表現への変換を管理するために使用されるヘルパー ツールです。 js_context.pack はそのオブジェクトを取得し、JSON シリアル化してテンプレートに渡すことができる値に変換します。ただし、現在はページのリロードが次の形式のエラーで失敗します: don't know how to package object:

これは、GameState が Telepath がまだ処理方法を知らないカスタム Python タイプであるためです。パックに渡されるカスタム タイプは、対応する JavaScript 実装にリンクする必要があります。これは、Adapter オブジェクトを定義し、それをテレパスに登録することによって行われます。 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 は、クライアント上で GameState インスタンスを構築するために使用される JavaScript コンストラクターの識別子であり、 js_args 定義はこのコンストラクターに渡されます。引数を使用して、指定された game_state オブジェクトの JavaScript 対応部分を再作成します。 Media クラスは、メディアをフォーマットするための Django の規則に従うファイルを示し、GameState の JavaScript 実装がここにあります。この JavaScript 実装がどのようなものになるかは後で説明します。GameStateAdapter の定義は Piece インスタンスをパッケージ化できるかどうかに依存しているため、今のところは 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 を右クリックします)コメントして [検査] または [要素の検査] を選択すると、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(&#39;DOMContentLoaded&#39;, event => {                 const gameElement = document.getElementById(&#39;game&#39;);                 gameElement.innerHTML = &#39;TODO: render the board here&#39;             });         </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(&#39;DOMContentLoaded&#39;, event => {                const gameElement = document.getElementById(&#39;game&#39;);                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(&#39;DOMContentLoaded&#39;, event => {                 const gameElement = document.getElementById(&#39;game&#39;);                 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 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
Pythonの主な目的:柔軟性と使いやすさPythonの主な目的:柔軟性と使いやすさApr 17, 2025 am 12:14 AM

Pythonの柔軟性は、マルチパラダイムサポートと動的タイプシステムに反映されていますが、使いやすさはシンプルな構文とリッチ標準ライブラリに由来しています。 1。柔軟性:オブジェクト指向、機能的および手続き的プログラミングをサポートし、動的タイプシステムは開発効率を向上させます。 2。使いやすさ:文法は自然言語に近く、標準的なライブラリは幅広い機能をカバーし、開発プロセスを簡素化します。

Python:汎用性の高いプログラミングの力Python:汎用性の高いプログラミングの力Apr 17, 2025 am 12:09 AM

Pythonは、初心者から上級開発者までのすべてのニーズに適した、そのシンプルさとパワーに非常に好まれています。その汎用性は、次のことに反映されています。1)学習と使用が簡単、シンプルな構文。 2)Numpy、Pandasなどの豊富なライブラリとフレームワーク。 3)さまざまなオペレーティングシステムで実行できるクロスプラットフォームサポート。 4)作業効率を向上させるためのスクリプトおよび自動化タスクに適しています。

1日2時間でPythonを学ぶ:実用的なガイド1日2時間でPythonを学ぶ:実用的なガイドApr 17, 2025 am 12:05 AM

はい、1日2時間でPythonを学びます。 1.合理的な学習計画を作成します。2。適切な学習リソースを選択します。3。実践を通じて学んだ知識を統合します。これらの手順は、短時間でPythonをマスターするのに役立ちます。

Python vs. C:開発者の長所と短所Python vs. C:開発者の長所と短所Apr 17, 2025 am 12:04 AM

Pythonは迅速な開発とデータ処理に適していますが、Cは高性能および基礎となる制御に適しています。 1)Pythonは、簡潔な構文を備えた使いやすく、データサイエンスやWeb開発に適しています。 2)Cは高性能で正確な制御を持ち、ゲームやシステムのプログラミングでよく使用されます。

Python:時間のコミットメントと学習ペースPython:時間のコミットメントと学習ペースApr 17, 2025 am 12:03 AM

Pythonを学ぶのに必要な時間は、人によって異なり、主に以前のプログラミングの経験、学習の動機付け、学習リソースと方法、学習リズムの影響を受けます。現実的な学習目標を設定し、実用的なプロジェクトを通じて最善を尽くします。

Python:自動化、スクリプト、およびタスク管理Python:自動化、スクリプト、およびタスク管理Apr 16, 2025 am 12:14 AM

Pythonは、自動化、スクリプト、およびタスク管理に優れています。 1)自動化:OSやShutilなどの標準ライブラリを介してファイルバックアップが実現されます。 2)スクリプトの書き込み:Psutilライブラリを使用してシステムリソースを監視します。 3)タスク管理:スケジュールライブラリを使用してタスクをスケジュールします。 Pythonの使いやすさと豊富なライブラリサポートにより、これらの分野で優先ツールになります。

Pythonと時間:勉強時間を最大限に活用するPythonと時間:勉強時間を最大限に活用するApr 14, 2025 am 12:02 AM

限られた時間でPythonの学習効率を最大化するには、PythonのDateTime、時間、およびスケジュールモジュールを使用できます。 1. DateTimeモジュールは、学習時間を記録および計画するために使用されます。 2。時間モジュールは、勉強と休息の時間を設定するのに役立ちます。 3.スケジュールモジュールは、毎週の学習タスクを自動的に配置します。

Python:ゲーム、GUIなどPython:ゲーム、GUIなどApr 13, 2025 am 12:14 AM

PythonはゲームとGUI開発に優れています。 1)ゲーム開発は、2Dゲームの作成に適した図面、オーディオ、その他の機能を提供し、Pygameを使用します。 2)GUI開発は、TKINTERまたはPYQTを選択できます。 TKINTERはシンプルで使いやすく、PYQTは豊富な機能を備えており、専門能力開発に適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。