@Satoh_D no blog

大分にUターンしたので記念に。調べたこととか作ったこととか食べたこととか

Django と Channelsでチャット作成のチュートリアルをやってみる(Tutorial Part 1: Basic Setup)

案件でチャットを作ることになりそうなので勉強中のDjangoでどこまでできるか確認メモ
調べてみるとChannelsを使えばできそうというということがわかったのでチュートリアルをやってみる

とりあえず今回は Tutorial Part 1: Basic Setup — Channels 2.4.0 documentation までやってみた

channels.readthedocs.io

前提

  • Django: 2.2.8(本当はDjang 3.0+がいいけどローカルがこれだったので。。)
  • Channels: 2.4.0

1. Django Channelsとは

Channels wraps Django’s native asynchronous view support, allowing Django projects to handle not only HTTP, but protocols that require long-running connections too - WebSockets, MQTT, chatbots, amateur radio, and more.

DjangoがHTTPだけでなくWebsockeet、MQTT、チャットボット、アマチュア無線など長時間の接続を必要とするプロトコルを扱えるようにする
ASGIがそれを可能にしているそうな

ASGI(the Asynchronous Server Gateway Interface)

Channelsで作られてたアプリケーションをアプリケーションサーバから切り離し、アプリケーションとミドルウェアとの間の標準インタフェース
WSGI拡張らしい

2. インストール

pipを利用してインストールを行う

$ pip install channels
$ pip list | grep channels
channels 2.4.0

<project-app>/settings.pyを編集しchannelsを有効化する

INSTALLED_APPS = [
    ...
    # 3rd party apps
    'channels',
    ...
]

<project-app>/asgi.pyを新規作成する
※ 今回は config/asgi.py とする

import os

from channels.routing import ProtocolTypeRouter
from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    # Just HTTP for now. (We can add other protocols later.)
})

# Django 2.2はASGIをサポートしていないので代替手段となる以下コードを記載する
import os

import django
from channels.http import AsgiHandler
from channels.routing import ProtocolTypeRouter

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
django.setup()

application = ProtocolTypeRouter({
  # Tutorialは "http": AsgiHandler() となっているが AsgiHandler でないと動かない
  "http": AsgiHandler,
  # Just HTTP for now. (We can add other protocols later.)
})

<projcect-app>/settings.pyASGI_APPLICATIONの設定を追記する

...
# Channles and ASGI Settings
ASGI_APPLICATION = 'config.asgi.application'
...

3. tutorial

3-1. Channlesのセットアップ

channles用アプリを作る

$ python manage.py startapp chat

今回はchat/views.py, chhat/__init__.pyしか使わないので他のファイルは削除する <project-app>/settings.pyに先程追加したchatを有効化する処理を追記する

INSTALLED_APPS = [
    ...
    # My applications
    'chat',
    ...
]

chat/templates/chat/index.htmlを作成する

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Chat Rooms</title>
</head>
<body>
    What chat room would you like to enter?<br>
    <input id="room-name-input" type="text" size="100"><br>
    <input id="room-name-submit" type="button" value="Enter">

    <script>
        document.querySelector('#room-name-input').focus();
        document.querySelector('#room-name-input').onkeyup = function(e) {
            if (e.keyCode === 13) {  // enter, return
                document.querySelector('#room-name-submit').click();
            }
        };

        document.querySelector('#room-name-submit').onclick = function(e) {
            var roomName = document.querySelector('#room-name-input').value;
            window.location.pathname = '/chat/' + roomName + '/';
        };
    </script>
</body>
</html>

chat/views.pyに以下を追記する

def index(request):
    # chat/templates/chat/index.html をビューとして返す
    return render(request, 'chat/index.html')

chat/urls.py, <project-app>/urls.pyにルーティングを追加する

# chat/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index')
]
# <project-app>/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    ...
    path('chat/', include('chat.urls')),
]

参考サイト