Django環境構築

※ IntelliJで「moduleにPythoinライブラリが構成されていません」のエラーが出る場合は
`⌘ + ;` でファイル | プロジェクト構造に移動し、インタプリンターに「Python3.xx」を指定

■ Django プロジェクトファイルの生成

```
django-admin startproject ‘プロジェクト名'
```

今いるディレクトリにプロジェクトディレクトリを生成する

■ プロジェクト内（大枠）でのsetting.pyの初期設定

```
LANGUAGE_CODE = ‘ja/'
TIMEZONE = ‘Asia/Tokyo’
```


■ Django アプリケーションを必要なだけ作れる
manage.pyのあるディレクトリ で（プロジェクト名と同じファイル名が存在するので注意）

```
python3 manage.py startapp ‘アプリ名'
```

dbファイル（sqlite3）と上記で指定したアプリケーションファイルが生成される


■ プロジェクト側のsettings.pyでつくったアプリケーションを登録する

```
INSTALLED_APPS = [ …
```

の中に、アプリ名＋.apps.＋アプリ名（大文字開始）＋Configと記載
（例：アプリ名→myappの場合）

```
‘myapp.apps.MyappConfig’
```

※ myappアプリの中の、appsファイルのMyappConfigというclassを利用するという意味
※ このclass名はstartappで自動で生成されたclass


■ プロジェクト側のurls.pyでinclude関数をインポート

```
from django urls import path, include
```

同じくurls.pyのurlpatternsの生成したアプリの中のurls.pyのルーティングに従う旨追記

```
urlpatterns = [
    …
    path(‘myapp/‘, include(‘myapp.urls’))
]
```

path関数の最初の引数は、ルートディレクトリの次のURL(~.com/xxxx/のxxxx)
次の引数で指定したapp内のurl内のurl指定で書くことができる

■ アプリケーション内にurls.pyファイルを作成し

```
from django.urls import path
from . import views

app_name = 'myapp'

urlpatterns = [
    path('', views.index, name='index')
]
```

from . import views　は基本的にdjangoアプリの2行目はこう書くでOK
アプリケーションディレクトリ内のviewsファイルを見にいくということ

urlpatterns はルーティング

■ views.pyに記載される内容が表示される（下記はサンプルコード）

```
from django.http import HttpResponse

def index(request):
    return HttpResponse('Hello World')
```

■ 実際にはtemplatesというディレクトリを作成しその中を編集していく
・djangoアプリ内にtemplatesディレクトリを作成
・templatesディレクトリの中にアプリ名と同名のディレクトリを作成
・さらにその中にindex.htmlを作成する

■ views.pyはtemplates内を読み込みにいくように設定

```
from django.shortcuts import render

def index(request):
    context = {
        ’name’ = ‘xxxx'
    }
    return render(request, ‘myapp/index.html’, context)
```

render関数の第一引数は必ずrequestを返す

index.html内には {{}}のように波括弧内に変数を渡すことができる（templateメソッド）
変数は contextの中に「辞書」を用意し、キーを変数として呼び出すことで紐づくvalueを表示する

■ models.py の編集
※(djangoではpythonのクラス=モデルを作成し、そのオブジェクト を操作することで間接的にDBとや取りができる仕組みになっている)

```
from django.db import models
from django.utils import timezone


class Day(models.Model):
    title = models.CharField(‘タイトル’, max_length=200)
    text = models.TextField(‘本文’)
    date = models.DateTimeField(‘日付’, default=timezone.now)
```

モデルを作るには
(models.Model)でmodels.Modelを継承した独自クラスを生成する

※djangoで現在時刻を取得したい場合は 標準ライブラリのdatetime.nowの代わりに 

```
timezone.now
```

他にもたくさんのfieldがある

■ makemigrations　する（変更や作成を伝える）
modelを触ったら作成したclassをdbへ登録

```
python3 manage.py makemigrations
```

■ migrateする（反映させる）

```
python3 manage.py migrate
```

■ 管理者画面を利用する

スーパーユーザーの作成

```
python3 manage.py createsuperuser
```

/adminが利用できるようになる。


■テストメモ
posts/tests.py

ログインユーザが、タイトルと本文を入力して、blog post を作れるか、みたいな感じのテストにする。

```
from django.test import TestCase
from django.contrib.auth.models import User


from .models import Post


class BlogTests(TestCase):
    @classmethod
    def setUpTestData(cls):
        # Create a User
        testuser1 = User.objects.create_user(
            username='testuser1',
            password='abc123!'
        )
        testuser1.save()


        # Create a blog post
        test_post = Post.objects.create(
            author=testuser1,
            title='Blog title',
            body='Body content...'
        )
        test_post.save()


    def test_blog_content(self):
        post = Post.objects.get(id=1)
        expected_author = f'{post.author}'
        expected_title = f'{post.title}'
        expected_body = f'{post.body}'
        self.assertEquals(expected_author, 'testuser1')
        self.assertEquals(expected_title, 'Blog title')
        self.assertEquals(expected_body, 'Body content...')

```

ローカルサーバが動いていたら Ctrl + c で一旦止めて、terminal 上から以下のコマンドを押下してテストする。

```
(blogapi-H-RPCYMU) $ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.125s


OK
Destroying test database for alias 'default'...
```

Django のテストコードは、こんな感じで書くらしい。