4/19~4/21に札幌で合宿をやっていました。いつもの id:tomio2480 主催の会です。
前回: 札幌で温泉合宿をやっていた - 偏った言語信者の垂れ流し
合宿では、 Django Meetupの資料 を直しつつ、いつも通り飯を作っていました。
4/19~4/21に札幌で合宿をやっていました。いつもの id:tomio2480 主催の会です。
前回: 札幌で温泉合宿をやっていた - 偏った言語信者の垂れ流し
合宿では、 Django Meetupの資料 を直しつつ、いつも通り飯を作っていました。
2024/4/13にDjangoMeetupTokyo #13を開催しました。
DjangoMeetupTokyo #13 - connpass
前回同様、もくもく会+ハンズオンの型式での開催をしました。
前回同様、私が資料を準備して、中級者向けハンズオンをやりました。
DjangoMeetupTokyo #13 中級者向けハンズオン — django-meetup-tokyo-13 ドキュメント
今回はDjangoのユーザー認証と、ユーザーに紐づくデータの取り扱いを学ぶ内容でした。
資料の内容を順番に説明し、手元で動かしてもらいながら、Djangoの機能について詳しく見ていきました。
本日、資料の手順を再検証、うまく動かなかったところなどを修正、説明を追記しました。
社内ライブラリのDart版の動作検証をするために、Dartの開発環境を準備する必要があったので、自分用にまとめておく。
Dartのコードを実行、ビルドするためにはSDKをセットアップする。
今回はUbuntu環境だったので、Linux用の手順でaptを使ってパッケージをインストールした。手順通りで特に問題なし。
dartの実行、ビルドなどは dart
コマンドからできる。
pub.devというサービスがパブリックなサードパーティパッケージのホスト先。
アプリの依存パッケージは pubspec.yaml
ファイルに記載。
dart pub get
コマンドで依存パッケージをインストールできる。
main.dart
ファイルを実行する場合、
dart run main.dart
main.dart
ファイルをコンパイルする場合、
dart compile <target> main.dart
<target>
には exe
(実行ファイル) や js
(JavaScript)などを指定できる。
exeの場合、Dartのランタイムを含む実行ファイルが出力される。クロスコンパイルの機能はないが、各コンパイル環境のOSで実行可能なバイナリを生成できる。
導入から実行、ビルドまではスムーズにできたのでよかったです。
Pythonのdataclasses.dataclassは普段からたまに使っていますが、良く使っている書き方を人に紹介するためにメモを残します。
dataclasses - データクラス - Python 3.12.2 ドキュメント
オブジェクトとdictで相互変換するクラスをdataclassで書くことがあります。
asdict
関数が便利です。リストで保持したいメンバー変数は、 field
関数を使って定義すれば、asdictでそのまま対象にできます。
また from_dict
メソッドは厳密に実装するなら引数のチェックなどをしてもよいですが、可変長のキーワード引数としてそのままコンストラクタに渡すように書けば、実装はシンプルです。
main.py:
from dacite import from_dict from dataclasses import dataclass, asdict, field @dataclass class Person: name: str age: int @classmethod def from_dict(cls, data: dict): return cls(**data) @dataclass class Group: name: str members: list[Person] = field(default_factory=list) @classmethod def from_dict(cls, data: dict): members_data = data.get("members", []) instance = cls(**data) if members_data: instance.members = [ Person.from_dict(member_data) for member_data in members_data ] return instance def main(): person = Person(name="Alice", age=30) group = Group(name="Team1", members=[person]) # groupをdictに変換すると、membersの要素もdictに変換される data = asdict(group) print(data) # dictからGroupオブジェクトを作成すると、membersの要素もPersonオブジェクトに変換される group2 = Group.from_dict(data) print(group2) # daciteを使えば、from_dictメソッドがなくても、dataclassのネストしたオブジェクトを作成できる group3 = from_dict(data_class=Group, data=data) print(group3) if __name__ == "__main__": main()
daciteを事前にインストール済み。
$ python main.py {'name': 'Team1', 'members': [{'name': 'Alice', 'age': 30}]} Group(name='Team1', members=[Person(name='Alice', age=30)]) Group(name='Team1', members=[Person(name='Alice', age=30)])
PersonとGroupのdataclassはどちらも親クラスの記述は無し。 from_dict
クラスは明示的に実装しています。
fieldを読み取って自動的に from_dict
の振る舞いをかえるような実装もできますが、継承関係を作らないのと、仕組みを複雑にしないためにあえてしていないです。
from_dict
メソッドの実装を省略したい場合は、 dacite のようなサードパーティパッケージを使うのもよさそうです。
Djangoフレームワークのテンプレートの継承について、基本的な内容です。
base.html
というファイルを作って、共通部分をまとめる話。
検索用に記事をまとめておきます。
※この記事は 力強くアウトプットする日の 20240301 のアウトプットです。
Djangoのドキュメントに例と説明があります。
Djangoのテンプレートには『継承』という仕組みがあります。
HTMLでウェブサイトを作る場合、複数のページでヘッダー部とフッター部を共通にすることがよくあります。 また、サイドバー、レイアウトなど、複数ページに渡って共通の構造とするパターンがとても多いです。
こうした構造のときにテンプレート継承がうまくハマります。
base.html
:
<html> <head> <meta charset="utf-8"> <title>{% block title %}{% endblock %}</title> <link rel="stylesheet" type="text/css" href="main.css"> </head> <body> {% block content %}{% endblock %} <script> // 全ページ共通で差し込むJavaScript </script> </body> </html>
test.html
:
{% extends "base.html" %} {% block title %}テストページ{% endblock %} {% block content %} <p> bodyタグ内のコンテンツ </p> {% endblock %}
views.py
:
from django.shortcuts import render def test(request): return render(request, "test.html")
<html> <head> <meta charset="utf-8"> <title>テストページ</title> <link rel="stylesheet" type="text/css" href="main.css"> </head> <body> <p> bodyタグ内のコンテンツ </p> <script> // 全ページ共通で差し込むJavaScript </script> </body> </html>
extendsタグで検証したテンプレートファイルでは、継承元のblockのうち、 変更したい部分 だけを記載することができます。 継承元のテンプレートに変更可能なblockがたくさんあっても場合、必要な部分だけ書けばいいので、記述量の削減につながります。
比較対象として、 includeタグ があります。 includeタグは、指定したテンプレートファイルの内容を、includeタグの記載位置に取り込みます。
includeの場合、この図の例のようにヘッダーとフッターが別のファイルに分離されます。HTMLの場合、 <html>
や <body>
も共通部に書きたい場合が多いと思いますが、閉じタグの対応が別々のファイルに含まれるのは見通しが良くないです。
また、includeだけで組み立てる場合は、includeタグを記述しないと対象のテンプレートが取り込まれないので、変更が少ししかないページでも記述量が多くなりがちです。
sshコマンドのオプションは、特定の環境下で作業する際にはよく使うのだけど、しばらく使わないと忘れてしまって毎度しらべているので、自分用にまとめておく。
※この記事は 力強くアウトプットする日の 20240216 のアウトプットです。
ssh -L [bind_address:]port:host:hostport destination
destination側から見た host:hostport を接続元の環境のportにフォワードできる。bind_addressを省略した場合はlocalhost
ssh -L 8888:localhost:8000 example.com
example.com
というsshでログインできるホストの localhost:8000
= 127.0.0.1:8000
を接続元の 8888
にフォワード。
接続元の端末で、 localhost:8888
につなぐと、 example.com上の localhost:8000
につながる、と考えてよい。
hostの部分はdestinationからネットワーク的に接続可能であれば、localhost以外も指定できるので、たとえばdestinationのサーバーからしか接続できない、内部ネットワーク上にあるホストに接続することもできる。
ssh -L 8888:192.168.100.123:3306 example.com
example.comというホストから見て、内部ネットワークにあたる192.168.100.123というIPv4アドレスのホストでデータベースサーバーが動作している場合(3306はMySQLのデフォルトポート)
このコマンドを実行した環境で、 localhost:8888
に接続すると、192.168.100.123:3306ポートにつながる。
もし、MySQLのコマンドから利用するのであれば、以下のようなコマンドになる。
mysql -h localhost -P 8888 -u db_user -p db_name
このように、example.comを踏み台として、その先にあるホストに接続が可能となる
ssh -D [bind_address:]port destination
destinationを起点としたSOCKSプロキシーを、接続元の環境のportで起動する。bind_addressを省略するとlocalhost。
SOCKSプロキシーはアプリケーションレベルでフォワーディングをしたいときに使う。主にウェブブラウザ。
ssh -D 8888 example.com
接続元の環境の localhost:8888
でSOCKSプロキシーが起動する。たとえば、example.com経由でしか接続できない内部ネットワーク上のウェブサイト(例: internal.example.com
)をブラウザで見たい場合。
ウェブブラウザのプロキシー設定で、SOCKSプロキシーのアドレスに localhost:8888
を設定し、ブラウザのアドレスバーに internal.example.com
と入力して接続すると、 example.com
のホストから通信を行うことになるため、閲覧できるようになる。
Chromeの場合、プロキシー設定は Proxy SwitchyOmega などの拡張を使うと有効/無効の管理がしやすい。
-L
オプションだと1つのホスト、ポートを対象としたフォワーディングだが、 -D
の場合はSOCKSプロキシーに対応したアプリからは、destinationのホスト経由で任意のホストに接続できる。
ssh -R [bind_address:]port:host:hostport destination
destinationのホストのportに接続すると、接続元の host:hostport
につながる。-L
の逆向きと考えればよい。
ssh -X destination
接続元環境のX11ディスプレイサーバーにdestination先のX11の接続をフォワーディングする。
destinationの環境でデスクトップアプリを起動し、画面だけを接続元環境に持ってきたい場合に使う。
たとえば、destination先のLinux環境にChromiumをインストールして起動し、接続元環境で画面の操作をしたい場合。VNCなどのリモートデスクトップ接続を利用しなくても、sshだけつながれば使える。
destinationを経由して更に別のホストにsshで接続したい(=多段SSHしたい)場合、ProxyCommandやncコマンドを使う例がでてくるが、最近のOpenSSHの場合は、 -J
オプションや ProxyJump
(.ssh/config
)を使えば記述がシンプルになる。
2024/1/28にDjangoMeetupTokyo #12を開催しました。
DjangoMeetupTokyo #12 - connpass
去年の夏以来の開催でしたが、今回は前回の倍ぐらいの参加者が集まりました。
コロナ禍が落ち着いてきて、勉強会などのイベントで基本的に制限がなくなったので、コロナ禍以前には活発だったオフラインの会を復活させていきたいなぁと個人的に思っています。
今回、私が資料を準備して、中級者向けハンズオンというのをやりました。
DjangoMeetupTokyo #12 中級者向けハンズオン — django-meetup-tokyo-12 ドキュメント
説明にある通り、「チュートリアルは理解できている、Djangoは使ったことあるけど、使いこなせてない~という人向けのハンズオン」というのを以前からやりたいなと考えていたものを、ようやく実施できました。
資料の内容を順番に説明し、手元で動かしてもらいながら、Djangoの機能について詳しく見ていきました。
好評のようでしたので、他の題材も考えて、またやれればよいなーと思います。