【Django入門】Djangoでブラウザ上に 'Hello World' を出力してみた。

## はじめに
　こんにちは、k_ukiです。現在Djangoでアプリ開発をしようと、キャッチアップを行っています。
　キャッチアップの中で、以下の項目について学びました。
- Djangoプロジェクトの作り方と生成されたファイルの用途
- 'urls.py','views.py'を使って'Hello World'を出力する方法。

今回は上記の項目を学ぶ際に実践したことをまとめていきます。

　学習する際に参考にした書籍は[こちら](https://www.amazon.co.jp/Django%E3%81%AE%E3%83%84%E3%83%9C%E3%81%A8%E3%82%B3%E3%83%84%E3%81%8C%E3%82%BC%E3%83%83%E3%82%BF%E3%82%A4%E3%81%AB%E3%82%8F%E3%81%8B%E3%82%8B%E6%9C%AC-%E7%AC%AC2%E7%89%88-%E5%A4%A7%E6%A9%8B%E4%BA%AE%E5%A4%AA/dp/4798066052/?_encoding=UTF8&pd_rd_w=UG9SA&content-id=amzn1.sym.22de103c-6ed7-4c73-a2e3-71576cce4007&pf_rd_p=22de103c-6ed7-4c73-a2e3-71576cce4007&pf_rd_r=KP7PMAVKRZRNEBFHRQM4&pd_rd_wg=yOZvm&pd_rd_r=e7ba9c2e-07ba-4e4b-9808-14200fa92e32&ref_=pd_gw_ci_mcx_mi)です。用語や処理の解説が詳しく書かれており、Webフレームワークが初めての人にはもちろんできますが、既に他のフレームワークを触れており、Djangoに移行してきた人に特におススメだと感じました。

## 0: Djangoのインストール
　初めてDjangoに触れる場合は、プロジェクトの作成の前にDjangoのインストールを行う必要があります。既にインストールが完了している方は、この章を読み飛ばしていただいて構いません。
　それでは、Djangoのインストールをしていきます。また、OSはWindowsで、WSL2でUbuntsuを立ち上げます。そしてその中にvenvの仮想環境を作ってコマンドを実行してきます。
```
$ pip install django==3.2
```
上記のコマンドを実行することで、バージョンが3.2のDjangoを指定しインストールすることができます。

## Djangoプロジェクトの作り方
　Djangoのインストールが完了したら早速プロジェクトを作っていきます。プロジェクトの作成には<b>startproject</b>コマンドを使用します。

```
$ django-admin startproject プロジェクト名
```
　今回は、Hello Worldを出力するのでプロジェクト名を「helloworldproject」にしています。
```
$ django-admin startproject helloworldproject
```
コマンドを実行すると以下のような構成のフォルダが生成されます。
![django1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341225/7dc70010-acb3-dd6d-01eb-e4bc85a9d265.png)

## 生成したファイルの確認

### \_\_init\_\_.py
　\_\_init\_\_.pyは、<b>ディレクトリがPythonパッケージであることを他のPythonファイルに知らせるためのファイル</b>になります。
　このファイルが存在することで、HttpResponseといったクラスや関数を他のファイルから呼び出すことができます。
### asgi.py
　asgi.pyはDjango3.0から追加されたファイルとなっており、簡単に説明すると非同期通信を簡単に行うための機能が含まれているファイルとなります。
### setting.py
　setting.pyはプロジェクト全体の設定を記述するファイルとなっております。秘密鍵の登録や、テンプレートの保管されているディレクトリの指定などをここで行います。
### urls.py
　urls.pyは、ブラウザから受け取ったリクエストを基に、後に作成するviews.pyに指示を送り、実行する処理内容などを決定するためのファイルになります。今回は、Hello Worldを表示するurlの決定や、表示するためのメソッドの指定をこちらに記述していきます。
### wsgi.py
　wsgi.pyはWSGI（Web Server Gateway Interface）という仕様に則ってウェブサーバーとDjangoの仲介を行うためのファイルとなります。
### manage.py
　manage.pyは、Djangoに予め用意されている機能を使用するためのファイルとなります。使用できる機能としては、webサーバの立ち上げを行う機能やマイグレーションファイルをmigrateする機能が挙げられます。Djangoに用意された機能を使用する場合、以下のようなフォーマットでコマンドを入力します。
```
$ python3 manage.py  コマンド名
# webサーバを機能する場合
$ python3 manage.py runserver
```
## urls.pyでリクエストを受け取る。
　プロジェクトの作成が完了したら、早速コードを記述していきます。まずはurls.pyに以下のようなコードを追加します。
```
from django.contrib import admin
from django.urls import path, include
from .views import helloworldfunc # 追加
urlpatterns = [
    path('admin/', admin.site.urls),
    path('helloworldurl/',helloworldfunc), # 追加
]
```
　コードの解説をします。
　上から3行目の"from .views import helloworldfunc"という記述で、views.pyで定義した"helloworldfunc"関数を呼び出しています。

　次に、下から二行目の記述の解説をします。
　path(url名, 処理名)では<b>リクエストのあったURLに対応した処理内容</b>を指定しています。今回の場合だと'helloworldurl/'というurlにアクセスがあった場合に、views.pyに定義された'helloworldfunc'を適用しろ、というような記述になっています。

## views.pyに処理内容を記述する
　前章で記述したhelloworldfunc関数を呼び出すためにviews.pyを作成し、記述していきます。urls.pyなどの同じ階層にviews.pyを作成します。
```
$ touch helloworldproject/views.py
```
　views.py内に移動し、コードを書いていきます。

```
from django.http import HttpResponse

def helloworldfunc(request):
    return HttpResponse('hello world')
```
　一行目の記述で、<b>HttpResponse </b>というクラスをインポートしています。HttpResponseとは、簡単にいうとブラウザ上に文字列やファイルを表示させるために使用するクラスとなります。今回の場合、最後の行で記述された'hello world'という文字列をブラウザ上に表示するために使用されています。

　<b>'def helloworldfunc(request)'</b>で、urls.pyで呼び出している関数の詳細を記載しています。引数にある（request）はウェブサーバから送信されてきたリクエストを指しています。引数にこれを記載しないと関数がリクエストを受け取ることができずエラーとなってしまいますので注意してください。

　記述が完了したら実際にHello Worldが表示されるかの確認を行います。
```
$ python3 manage.py runserver
```
　コマンド実行後、"127.0.0.1:8000/helloworldurl/"にアクセスします。「hello world」と表示されていれば成功です。
![django2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341225/72e3f3c7-95aa-4b2b-c0c7-887dbfc58a83.png)
　無事表示が確認されたら今表示されている文字列をhtmlのh1タグにしてみようと思います。views.pyのhelloworldfunc関数の返り値を以下のように編集します。
```
return HttpResponse('<h1>hello world</h1>')
```
　ページを更新してみましょう。h1タグが適用され太字になっていたら成功です。
![django3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341225/9ae01404-b2ae-dc84-9ff2-8d1e2aabd5a7.png)

## class-based viewとfunction-based view
　DjangoにおけるViewページの表示方法は大きく二つあり、<b>class-based view</b>と<b>function-based view</b>です。本章では、この二つの違いについて話していきます。
### class-based view
　class-based viewは、簡単に説明すると<b>Djangoが元々用意してくれていたメソッドを使用し実装していく方法</b>になります。例えば、データの一覧ページを作成した場合には<b>ListView</b>クラスを使用します。メソッドが予め用意されているため、実装難易度は低くなりますが、その分拡張性が乏しくなるという欠点もあります。

### function-based view
　function-based viewは、class-based viewとは異なり<b>自身で一から処理を実装していく方法</b>になります。前章のHello Worldを出力した関数もfunction-based viewになります。全部自身で実装するため拡張性は高いですが、その分実装難易度が高いという欠点があります。

## class-based viewでHello Worldを出力してみる
　この章では前述したclass-based viewを用いてHello Worldを実装してみます。
　まずは、urls.pyを編集します。
```
from django.contrib import admin
from django.urls import path 
from .views import helloworldfunc,HelloWorldClass # HelloWorldClassの記述を追加
urlpatterns = [
    path('admin/', admin.site.urls),
    path('helloworldurl/',helloworldfunc),
    path('helloworldurl2/',HelloWorldClass.as_view()),# 追加
]

```
　三行目では、views.pyで記述するHelloWorldClassの呼び出しをおこなっています。
　また、下から二行目の記述では"helloworldurl2/"というURLにアクセスした際に、"HelloWorldClass"を実行しろという記述をしています。また、クラスを呼び出す際には末尾に<b>as_view()</b>メソッドをつける必要があります。

　次に、views.pyを編集します。
```
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加

def helloworldfunc(request):
  responseobject = HttpResponse('<h1>hello world</h1>')
  return responseobject # return HttpResponse('hello world')

# 以下を新たに記述
class HelloWorldClass(TemplateView):　
  template_name = 'hello.html'
```
　上から二行目の解説をします。ここでは、Djangoがあらかじめ用意しているTemplateViewというクラスを呼び出しています。この記述をすることでTemplateViewクラスに含まれる関数などを使えるようになります。
　次に、下二行の新たに追加したクラスについて解説します。HelloWorldClassの引数にTemplateViewを指定し、TemplateViewを継承することでHelloWorldClassでTemplateViewの関数を使用できるようにしています。<b>template_name</b>はブラウザに表示するhtmlファイルを指定するのに用いられます。今回はhello.htmlを指定しています。

　先ほどの記述でtemplate_nameにhello.htmlを指定していましたが、hello.htmlはどこに保存するかの指定がまだできていません。そのためsetting.pyを編集し、テンプレートファイルの保管先を指定してあげる必要があります。

setting.pyの以下の部分を編集します。
```
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'], # 元々[]となっている部分をこのように変更
```
　BASE_DIRは"helloworldproject"のディレクトリを指しています。つまり、この記述では「テンプレートは./helloworldproject/templatesというフォルダにあるファイルを指している」という設定をおこなったことになるのです。

　manage.pyと同じ階層にtemplatesフォルダを作成し、その中でhello.htmlを作成します。その後、hello.htmlに"hello world"という文字列を追加します。

ここまでが完了したら再度サーバーを起動し確認してみます。
```
$ python3 manage.py runserver
```
"http://127.0.0.1:8000/helloworldurl2/ "にアクセスし、hello worldと表示されていれば成功です。
![django4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341225/57dae6ab-abe2-f7c2-403e-87cf95ed4e35.png)

これで、class-based viewとfunction-based viewの両方でHello Worldを表示されることができました。

## 最後に
以上が、私が今回実践したことになります。今回の学習では以下のことを学びました。
- プロジェクトの作成方法,作成されたファイルの用途
- urls.py,views.pyの記述方法
- class-based viewとfunction-based viewの違いとそれぞれの用法

次は、簡単なCRUDのアプリを作ってみようと思います。