スポンサードリンク



こんにちは。sinyです。

この記事はDjango Advent Calendar 2021の11目の記事です。

この記事では、Djangoで依存チェーンドロップダウン選択リストを作成する方法を簡単にご紹介します。

「Web画面で都道府県をリストから1つ選択すると、選択した都道府県に対応する市区町村だけが一覧表示される」といった機能を例にして実装してみます。

実装物のデモ画面は以下の通りです。

 

サンプルコードは以下のGITHUBリポジトリにUPしていますので参考にしてみてください。

市区町村データのダウンロード

今回は、市区町村のJsonデータをあらかじめダウンロードしておき、Djangoプロジェクト内で利用する形とします。

都道府県のJsonデータは以下のサイトから拝借させていただきました。

上記サイトの「都道府県 - 市町村エンドポイント」の下記URLをクリックします。

https://geolonia.github.io/japanese-addresses/api/ja.json

都道府県名のJsonデータが表示されるので「右クリック→名前を付けて保存」→ja_prefecture.jsonとして一旦保存しておきましょう。

Djangoの初期設定

まず最初に必要なモジュールの導入、プロジェクト、アプリの作成と初期設定を行っておきます。

今回は以下のモジュールをインストールします。

プロジェクトとアプリを作成します。

settings.pyを以下の通り設定します。

 

また、Djangoプロジェクトフォルダ直下にstatic/dataフォルダを作成して先ほどダウンロードしたja_prefecture.jsonファイルを配置しておきましょう。

フォームの定義

app/forms.pyを新規に作成して以下のコードを定義します。

 

各関数の役割は以下の通りです。

関数名 処理内容
readJson
ja_prefecture.jsonファイルを読み込む関数
get_prefecture
ja_prefecture.jsonから都道府県名の全情報を返す関数
return_cities_by_prefecture
 
引数に渡した都道府県名から市区町村のデータを返す関数

 

AddressFormクラスは都道府県を選択するリストフォームの定義です。
formのChoiceFiledを使ってchoicesにget_prefecture関数を指定してjsonファイルから都道府県名を表示させるようにしています。

 

ビューの定義

次にロジックをビューに定義していきます。

app/views.pyに以下のコードを追加しましょう。

 

各関数の処理内容は以下の通りです。

関数名 処理内容
processForm
http://127.0.0.1:8000/process-formにアクセスした際にgetメソッドだったら、都道府県を選択するフォーム(AddressForm)を表示し、POSTメソッドだったら選択された市区町村データをフォームの保存するような想定です。
※今回は特に実際に保存はしていません。
getPrefecture
この関数はテンプレート側で選択した都道府県情報をAjaxで受け取り、ビュー側で都道府県に該当する市区町村データを取得してテンプレート側に市区町村データを返してあげる関数です。

 

 

URLパターンの定義

プロジェクトルートのurls.pyは以下の様に設定します。

appフォルダにurls.pyを作成し、以下の通り定義します。

1番目のURLパターンはhttp://127.0.0.1:8000/process-formにアクセスした際に都道府県の選択画面を表示するものです。

2番目は選択画面で選択された都道府県名をAjaxで通信で受け取るためのURLパターンです。
getPrefecture関数が呼ばれて都道府県に対応する市区町村データをテンプレートに返します。

テンプレートの作成

 

最後にテンプレートを作成します。
まずベースとなるbase.htmlを以下の通り記載します。
bootstrapを使ったシンプルな定義ですので、説明は省略します。

 

メインとなるaddress.htmlを以下の通り定義します。

 

冒頭でbase.htmlを拡張、フォームデザインを整えるためにwidget_tweaksをロードしておきます。

都道府県の選択と市区町村データの選択フォームの定義が以下の部分です。

 

{{ form.country}}で都道府県のリスト選択フォームを表示しています。
また、以下の部分で市区町村データをリスト表示するフォームを定義しています。

 

処理の流れとしては、「{{ form.country}}で選択された都道府県名をajaxでビュー側に返し、市区町村データを取得してテンプレートに戻してid="id_city"に市区町村データのリストを表示する」という感じになります。

最後にAjax通信の定義が以下の箇所です。

 

id_prefectureの要素に変更があった場合(=都道府県名を選択する)に都道府県の情報をprefecture変数にセット後、
urlで指定したDjangoのURLパターン("{% url 'get-prefecture' %}")にprefectureを引数にして渡してあげます。
そうすると戻り値に選択した都道府県に対応する市区町村データが返ってくるので、id="id_city"の要素に市区町村データを組み込んであげることで、「選択した都道府県に対応する市区町村データだけがリスト表示される」という機能が実現できます。
今回は都道府県のデータをJson形式で用意しましたが、APIを利用する場合はforms.pyで定義したget_prefecture関数やreturn_cities_by_prefecture関数の部分をAPIコール関数に置き換えればよいでしょう。

他にもいろいろなやり方があると思いますが、1つの方法として参考にしていただければ幸いです。

 

おすすめの記事