PyCharm で Django アプリを作成する
Django は開発者がアプリケーションをすばやく構築できるようにすることを主な目的としています。 このフレームワークを習得すると、概念を本番運用が可能なウェブアプリケーションに変えるまでの行程が短縮されます。 ただし、その行程をさらに短縮したい場合は PyCharm での Django アプリの作成方法を学習することをお勧めします。
このチュートリアルでは、現在地の現在の気温を表示する簡単な Django アプリケーションを作成する手順をすべて説明します。 また、他のランダムな場所の天候を参照できるようにすることで、アプリに対話性を導入したいと思います。
このチュートリアルでは、以下について学習します。
- PyCharm で Django プロジェクトを作成する。
- モデル、ビュー、およびテンプレートを記述する。
- API を呼び出して応答を処理する。
- データベースに接続してデータを挿入する。
完全なアプリケーションのコードを取得するには、リポジトリをクローンしてください。 クローン操作についての詳細は、PyCharm のドキュメントをご覧ください。
前提条件
このチュートリアルは Python の経験が 2~3 年ある開発者を対象としています。 したがって、お使いのコンピューターに Python がインストール済みであることが前提です。 インストール済みでなくても大丈夫です! 必要な Python のバージョンは、PyCharm で最初のプロジェクトを作成する際にダウンロードしてインストールできます。
Django のサポートは Professional の機能であるため、PyCharm Professional のインストールが必要です。 新規ユーザー向けには 30 日間の試用期間を提供していますし、学生または教師の方は無料教育用ライセンスをお申し込みいただけます。 このチュートリアルは 新しい UI を有効にした PyCharm 2023.1 で作成されました。
他のオペレーティングシステム向けの情報とインストール手順は、PyCharm のドキュメントをご覧ください。
アプリの制作を開始する
はじめの一歩です。 ここで実施する手順は多くありませんが、最終的には基本的なレベルでアプリを実行できるようになります。
PyCharm で Django プロジェクトを作成する
プロジェクトを作成するには、PyCharm を起動して New Project(新規プロジェクト)をクリックします。 PyCharm がすでに起動している場合は、メインメニューから File(ファイル)| New Project(新規プロジェクト)を選択します。
New Project(新規プロジェクト)ウィンドウが開いたら、以下のように指定します。
- プロジェクトタイプには Django を選択します。
- プロジェクトの保存先ディレクトリ名を入力します。 このディレクトリ名はプロジェクト名としても使用されます。
- 新しい Django プロジェクト用の仮想環境を作成します。PyCharm はこの環境に依存関係をインストールします。 このチュートリアルの目的のために、virtualenv オプションを選択します。
- PyCharm ではプロジェクト内ですぐに Django アプリケーションを作成できます。 ここでは必ずアプリケーションに名前を付けてください。
準備が整ったら、Create(作成)をクリックします。 PyCharm がファイル構造を作成し、Django やその他の必要な依存関係をインストールします。
ウィンドウの最上部にある Run (実行)アイコンをクリックして Django サーバーを起動します。
Run(実行)ツールウィンドウが開きます。 リンクをクリックしてブラウザーウィンドウを開きます。
わずか数分で Django サーバーが PyCharm 内で動作するようになりました。 出だしは順調ですね。でも、ここからが本番です。
はじめてのビューを記述する
アプリケーションロジックの作成に取りかかりましょう。 Django では views.py にクラスまたは関数を記述してアプリケーションロジックを作成します。
PyCharm ウィンドウの左上にあるフォルダーアイコンをクリックするか、⌘1 / Alt+1 を押すと、プロジェクトの構造をいつでも参照できます。
このチュートリアルでは、⇧ (Shift) を2 回押して Search Everywhere(どこでも検索)ウィンドウを開くなど、時間の節約になるショートカットが使用されています。 このショートカットを使うと、プロジェクトファイル、設定、アクションなど、実質的にあらゆる項目を検索することができます。
では、ショートカットを使用して views.py を開きましょう。
「views」と入力し、meteo にある views.py にカーソルを移動し、Enter を押します。
views.py がエディターのタブで開きます。 まずは temp_here
関数を記述しましょう。この関数は現在地の現在の気温を返します。
エディターに以下のコードを貼り付けます。
import requests def temp_here(): location = geocoder.ip('me').latlng endpoint = "https://api.open-meteo.com/v1/forecast" api_request = f"{endpoint}?latitude={location[0]}&longitude={location[1]}&hourly=temperature_2m" return requests.get(api_request).json()
何を行っているのでしょうか? まず、API 呼び出しに必要な requests
ライブラリをインポートしています。 import ステートメントに赤い波線が引かれている場合は、選択された Python インタープリターではパッケージを使用できないということです。
赤い波線が引かれた場所にマウスポインターを移動し、Install package requests(requests パッケージのインストール)を選択します。
現在の気温を取得するため、temp_here
が Weather Forecast API への呼び出しを行っています。 これは API キーを必要としない無料の API です。 ここで知っておく必要があるのは、エンドポイント(https://api.open-meteo.com/v1/forecast)と座標だけです。 座標については、Geocoder というさまざまな場所の座標を取得できる非常に単純な Python ライブラリを使用します。
赤い波線でハイライトされている geocoder
にキャレットを置いて ⌥Enter / Alt+Enter を押し、使用できるクイックフィックスを表示します。 Install and import package ‘geocoder’(パッケージ ‘geocoder’ のインストールとインポート)を選択します。
PyCharm がパッケージをインストールし、ファイルの先頭に import ステートメントを追加します。
では、テストリクエストを作成して期待通りに問題なく動作することを確認してみましょう。 Python コンソールで関数を呼び出すのが最も簡単です。
時間の節約になるもう 1 つの機能、Find Action(アクションの検索)を使用しましょう。 マウスでメニューを操作したり、多数のショートカットを記憶したりしなくても、⇧⌘A / Ctrl+Shift+A を押すだけで Run File in Python Console(Python コンソールでファイルを実行)を検索できます。
このアクションのすべての文字を入力する必要はありません。 'rufipy' のように入力しても、目的の結果を得られます。
このコマンドを実行すると、PyCharm は import と関数の定義をコンソールに読み込みます。 では、temp_here
を呼び出しましょう。 Tab を押すと、コード補完を使用できます。
コンソール出力で API 応答を調べます。 非常に長い文字列ですが、以下の説明図を参照してください。
自分で応答を調べる場合は、以下の手順に従います。
- コンソールの出力を 3 回クリックし、⌘C / Ctrl+C を押して応答をクリップボードにコピーします。
- ⇧⌘N / Ctrl+Alt+Shift+Insert を押してスクラッチファイルを作成し、JSON ファイルタイプを選択します('js…' を入力するだけで見つかります)。
- 応答を貼り付けたら Reformat Code(コードの整形)アクションを適用します。 Find Action(アクションの検索)を使用するか、⌥⌘L / Ctrl+Alt+L を押すことができます。
必要な情報は、temperature_2m
キーの hourly
要素にあります。 このキーは値のリストを参照しています。
現在の気温を取得するには、現在の時間をインデックスとして渡す必要があります。 たとえば、現在の時間が 14:30 である場合はリストの 14 番目の項目を取得します。
temp_here()['hourly']['temperature_2m'][14]
で必要な情報を取得できるかどうか確認してみましょう。
現在の時間に従って '14' を置き換えたコードをコンソールに入力します。
現在地の現在の気温は 14.9 °C となりました。 あなたの結果はどうなりましたか?
API 応答から現在の気温を抽出するように関数を変更しましょう。
def temp_here(): location = geocoder.ip('me').latlng endpoint = "https://api.open-meteo.com/v1/forecast" api_request = f"{endpoint}?latitude={location[0]}&longitude={location[1]}&hourly=temperature_2m" now = datetime.now() hour = now.hour meteo_data = requests.get(api_request).json() temp = meteo_data['hourly']['temperature_2m'][hour] return temp
datetime
を忘れずにインポートしましょう。
Python コンソールツールバーの左上にある Rerun(再実行)をクリックし、更新した関数定義を読み込み直してから temp_here
をもう一度呼び出します。
この結果が temp_here
関数のコードを変更する前の結果と異なっている場合、settings.py の TIME_ZONE
値が誤っている可能性があります。
詳細については、Django のドキュメントをご覧ください。
この設定に素早くアクセスするには、⇧ (Shift) を 2 回押し、Tab を数回押して Symbols(シンボル)に切り替え、'time…' を入力します。
では、temp_here
をビュー関数に変換しましょう。 この関数を Django にビューとして認識させるには、HttpRequest オブジェクトを最初のパラメーターとして受け取る必要があります。このパラメーターの名前は通常 request
です。 HttpResponse オブジェクトも返すようにする必要があります。
views.py は以下のようになります。
from datetime import datetime import geocoder as geocoder import requests from django.http import HttpResponse def temp_here(request): location = geocoder.ip('me').latlng endpoint = "https://api.open-meteo.com/v1/forecast" api_request = f"{endpoint}?latitude={location[0]}&longitude={location[1]}&hourly=temperature_2m" now = datetime.now() hour = now.hour meteo_data = requests.get(api_request).json() temp = meteo_data['hourly']['temperature_2m'][hour] return HttpResponse(f"Here it's {temp}")
ご覧のとおり、ほとんど変更していません。temp_here
が request
を引数として受け取るようになり、HttpResponse
を文字列を一緒に返すようになっています。
摂氏の代わりに華氏を使用する場合は、API リクエストに temperature_unit
パラメーターを追加するだけで非常に簡単に実現できます。
api_request = f"{endpoint}?latitude={location[0]}&longitude={location[1]}&hourly=temperature_2m&temperature_unit=fahrenheit"
摂氏を使用する場合は、この変更を省略してください。
URL の構成
ブラウザーからアプリにアクセスする方法を構成するには、urls.py を更新します。 前述のように Shift を 2 回押し、検索する URL を入力して開きます。
urlpatterns
に以下の行を追加します。 Reformat Code(コードの整形)アクションまたは ⌥⌘L / Ctrl+Alt+L を使用すると、貼り付けた後のインデントを簡単に復元できます。
path("", include('meteo.urls')),
django.urls.include
から include
を忘れずにインポートしましょう。
'meteo.urls'
はまだ存在しないファイルであるため、未解決の参照であることが黄色の波線で示されます。 これは、次のステップで修正します。
Django プロジェクトには通常、複数のアプリが含まれます。 現時点ではそうでなくても、今後のプロジェクト開発を考慮する必要があります。 そのため、アプリケーションごとの urls.py を対応するフォルダーに作成し、プロジェクトの urls.py にすべてを含めます。
では、meteo アプリケーションのフォルダーに urls.py を作成しましょう。
Project(プロジェクト)ツールウィンドウで meteo ディレクトリを右クリックします。
New(新規)> Python File(Python ファイル)を選択し、urls と入力します。
新たに作成されたファイルが開きます。 そのファイルに以下のコードを入力します。
from django.urls import path from . import views urlpatterns = [ path('meteo/', views.temp_here, name='temp_here'), ]
ブラウザーで <サーバーアドレス>/meteo に移動すると、views.py の temp_here
関数が呼び出され、その戻り値がブラウザーに表示されます。
動いてます!
右上の Rerun(再実行)ボタンをクリックして Django サーバーを再実行し、アクションを確認します。
ブラウザーで http://127.0.0.1:8000/meteo/ を開きます。 以下のように表示されるはずです。
ブラウザーを開いてアドレスを入力したくない場合や Django サーバーを再起動するたびに手動でページを再読み込みしたくない場合は、PyCharm の構成で自動化できます。
Run(実行)ウィジェットのドロップダウンリストを開き、Edit configurations(構成の編集)を選択します。
左ペインにあるプロジェクトの構成を選択し、Run browser(ブラウザーの実行)チェックボックスをオンにし、URL に meteo を追加します。
OK をクリックして変更を適用します。
技術的にはアプリは動作していますが、 ブラウザーでの見栄えはあまりよくありません。「ランダムな場所の天気」機能もまだ備わっていません。 次のステップではこのような問題を解決するため、テンプレートを導入してデータをインポートします。
エクスペリエンスを改善する
テンプレートを追加する
views.py に戻り、もう一度 temp_here
関数を変更しましょう。 まだ meteo/urls.py を開いているのであれば、すぐに移動できます。 ⌘ / Ctrl を押したままマウスポインターを temp_here
に移動し、ハイパーリンクに変わったらクリックします。
return ステートメントの前に新しい行を追加し、‘template = loader’ と入力します。
⌥Enter/ Alt+Enter を押して、django.template.loader
から loader
をインポートするクイックフィックスを使用します。
次に、get_template()
を使用して index.html をテンプレートとして読み込みます。
template = loader.get_template('index.html')
return ステートメントを以下の 2 行に置き換えます。
context = {'temp': temp} return HttpResponse(template.render(context, request))
Index.html はまだ存在しないため、黄色の波線でハイライトされます。 そこにマウスポインターを移動し、Create template index.html(テンプレート index.html の作成)を選択します。
OK をクリックします。 PyCharm が index.html を作成し、編集用に開きます。
現在、このファイルは空です。 Live Template(ライブテンプレート)を使用してテンプレート html コードを挿入しましょう。 html:5 と入力し、Tab を押します。
html ページの表示コンテンツは <body></body>
タグに囲まれた部分です。
その部分に以下のコードを挿入します。
<h1>Temperature at your location:</h1> <h2>{{ temp }} ℃</h2>
ここで、temp
はビューからテンプレートに渡される変数です。 テンプレートを表示すると、変数の名前と値がディクショナリに保存されて渡されます。 この処理は {‘temp’ : temp}
を上記の views.py のコンテキスト変数に割り当てることで行っています。
摂氏記号の Unicode 表記は ℃
です。 華氏の場合は ℉
を使用します。
では、変更内容を確認してアプリが期待どおりに動作するか確認するため、Django サーバーを再実行しましょう。 前述のように実行構成を編集した場合、ブラウザーウィンドウが自動的に開きます。
データベースとモデルを作成する
API からランダムな場所の気温データを取得するには、場所の座標を提供する必要があります。
それには CC BY 4.0 でライセンス提供されている Juanma Hernández の World cities データベースを使用しましょう。 データベースをダウンロードして、アーカイブから worldcities.csv を取り出します。 Kaggle のアカウントをお持ちでない場合は、登録が必要です。
また、Django が自動生成した db.sqlite3 データベースを PyCharm プロジェクトに追加する必要があります。
これを行うには、以下の手順を実行します。
- 右側のデータベースアイコンをクリックして Database(データベース)ツールウィンドウを開きます。 ⌘E / Ctrl+E を押すと、すべてのツールウィンドウにアクセスできます。
- ツールウィンドウの左上にある + をクリックし、Data Source(データソース)> SQLite を選択します。 'sq…' と入力すると、必要なオプションに素早くアクセスできます。
- File(ファイル)フィールドの横にある … をクリックし、プロジェクトフォルダーの db.sqlite3 ファイルを参照します。
- データベースドライバーのインストール、更新、または切り替えが必要な場合があります。 ウィンドウの下に警告が表示される場合は、リンクをクリックして必要な操作を実行してください。
- OK をクリックします。
データをデータベースにインポートするには、worldcities.csv を Database(データベース)ツールウィンドウの db.sqlite3 にドラッグアンドロップします。 ダイアログが開いたら、city、lat、lng、country、および id 以外の不要な列を削除します。
db.sqlite3 データベースに worldcities テーブルが含まれました。
それをダブルクリックすると、エディターで中身を確認できます。
Django はモデルを使用してデータベースを操作します。 モデルを作成して worldcities テーブルのデータを読み込めるようにしましょう。
- ⌥R / Ctrl+Alt+R を押して manage.py タスクコンソールを起動します。
- inspectdb worldcities と入力し、Enter を押します。
- コンソール出力の
Worldcities
を meteo\models.py にコピーします。 - id フィールドの
null=True
をprimary_key=True
に置き換えます。
すると、以下のようになります。
from django.db import models class Worldcities(models.Model): city = models.TextField(blank=True, null=True) lat = models.FloatField(blank=True, null=True) lng = models.FloatField(blank=True, null=True) country = models.TextField(blank=True, null=True) id = models.IntegerField(blank=True, primary_key=True) class Meta: managed = False db_table = 'worldcities'
機能を追加する
今のところ、views.py には現在地の現在の気温に関する情報を返す関数(temp_here
)しかありません。 関数をもう 1 つ追加して、ランダムな場所の気温を表示するようにしましょう。 API から現在の気温データを取得する必要もあるため、Python のベストプラクティスに従って該当する機能を別の関数に移動します。
PyCharm では、このような移動を Extract method(メソッドの抽出)リファクタリングを使って簡単に実行できます。
別の関数に移動する必要のある行を選択し、⌥⌘M / Ctrl+Alt+M を押します。 または、Find Action(アクションを検索)を使用します。
Method name(メソッド名)フィールドに get_temp
を入力して OK をクリックします。 location
を唯一のパラメーターとする get_temp
関数ができました。
get_temp
関数呼び出しにより、現在の場所の気温を取得できます。
temp_somewhere
関数を作成しましょう。 この関数はランダムな都市の座標を get_temp
に渡します。
まず、Python コンソールでプロトタイプを作成しましょう。 コンソールを開き、以下のコードを貼り付けます(ImportError
が発生する場合はコンソールを閉じて開き直してください)。
from meteo.models import Worldcities random_item = Worldcities.objects.all().order_by('?').first()
worldcities テーブルからデータを取得する必要があります。 これはモデルを使って行うため、models.py から Worldcities
モデルをインポートします。
次に、すべてのオブジェクトを order_by(‘?’)
でランダム化し、first()
で最初のオブジェクトを取得します。 Python console(Python コンソール)ツールウィンドウの右側に Variables(変数)タブがあります。 random_item ノードを展開し、random_item の内容を確認します。
temp_somewhere
関数の完全なコードは以下のようになっています。
def temp_somewhere(request): random_item = Worldcities.objects.all().order_by('?').first() city = random_item.city location = [random_item.lat, random_item.lng] temp = get_temp(location) template = loader.get_template("index.html") context = { 'city': city, 'temp': temp } return HttpResponse(template.render(context, request))
context
に気温だけでなく都市名も含まるようになりました。 テンプレートを編集し、この情報も表示するようにしましょう。
<> アイコンがガターに表示されているのに気付きましたか? このアイコンをクリックすると、index.html に素早く切り替わります。
<h1></h1>
タグに囲まれたテキストを {{ city }}
に置き換えます。
ガターアイコンをクリックして、temp_here
関数に素早く移動します。
この関数を city
変数も渡すように変更する必要があります。
temp_here
関数は、https://127.0.0.1/meteo ページがブラウザーで開かれたときに呼び出されます。これは meteo/urls.py で構成しました。
そこに戻り、https://127.0.0.1/meteo/discover にアクセスがあったときに temp_somewhere
が呼び出されるように指定しましょう。
urlpatterns = [ path('meteo/', views.temp_here, name='temp_here'), path('meteo/discover', views.temp_somewhere, name='temp_somewhere'), ]
index.html に戻り、/discover ページとホームページへのリンクを追加します。 ホームページへのリンクは、必ず現在の場所の気温を表示します。 この作業にかかる時間を短縮するには、ライブテンプレートとコード補完が役立ちます。
HTML ファイルの段落とリンクにライブテンプレートを使用するには、それぞれ 'p' と 'a' を入力して Tab を押すだけです。
使用できるライブテンプレートの全リストを確認するには、設定を開き(⌘ / Ctrl+Alt+S)、Editor(エディター)> Live Templates(ライブテンプレート)に移動し、右ペインの Zen HTML ノードを展開します。
サーバーを再実行してアプリケーションを操作してみましょう。
これで終わりではありません
アプリは動作していますが、まだまだ改善の余地があります。 最も明らかなのは視覚的な外観ですが、他の機能も追加できます。
CSS を使用する
Django アプリケーションの見栄えを素早く簡単に改善するには、CSS を使用するのが一番です。 たとえば、Simple.CSS を使用できます。
index.html の <head></head>
タグの中に以下の行を挿入してください。
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
外観が以下のように変わります。
リンクをボタンに置き換えても外観が改善されます。
これを行うには、index.html の <p></p>
タグの中にあるリンクを以下の HTML コードに置き換えます。
<div style="display: flex;"> <form action="./discover"> <input type="submit" value="Check other places"/> </form> <form action="."> <input style="background: #dc3545" type="submit" value="Home"/> </form> </div>
index.html の編集結果は PyCharm からブラウザーに切り替えなくても確認できます。 エディターウィンドウの右上にマウスポインターを移動し、Built-in Preview(ビルトインプレビュー)を選択します。
Bootstrap を使用する
Bootstrap は強力な無料のフロントエンドツールキットです。 これを素早く Django アプリに適用するには、以下のように index.html を編集します(詳細は Bootstrap クイックスタートガイドをご覧ください)。
- HTML の head に
link
タグを追加します(前のステップの simple.css を置き換えます)。
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
2. このコードと以下のコードを <body></body>
タグの中に追加します。
<div class="container text-center"> <h1>{{ city }}</h1> <h2>{{ temp }} ℃</h2> <div class="btn-group" role="group"> <button type="button" class="btn btn-outline-primary" onclick="location.href='./discover'">Check other places </button> <button type="button" class="btn btn-danger" onclick="location.href='.'">Home</button> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
結果を確認します。
Bootstrap にはアプリの外観をカスタマイズするための方法が豊富に備わっています。 必要なすべての情報は、ドキュメントをご覧ください。
スキルチェック
worldcities データベースの country
フィールドを Worldcities
モデルに追加しましたが、アプリのどの場所にもそのデータを使用していません。 そこで、力試しをしましょう。アプリに都市名だけでなく国も表示するようにしてください。 結果は以下のようになるはずです。
まとめ
このチュートリアルでは以下について学習しました。
- PyCharm で Django プロジェクトを作成する。
- ビューを記述してテンプレートを作成する。
- API を呼び出して応答を処理する。
- データベースを接続してデータをインポートする。
- CSS と Bootstrap を適用してアプリの視覚的な外観を改善する。
オリジナル(英語)ブログ記事の作者: