python

Django入門その2

djangoを使用してプロジェクトを作成するには、djangoのフレームワークで使用するファイル群を持ってくる必要があります。
それは、下記のコマンドで一発で持ってくることができます。
django-admin startproject mysite
mysiteはプロジェクト名なので任意につけることができますが、一部命名ができない名前もあります。それはpythonで使用されているモジュール名です。例えば、testなどがあります。
django-admin start-project test
これを実行すると、「CommandError: ‘test’ conflicts with the name of an existing Python module and cannot be used as a project name. Please try another name.」と言われます。pythonモジュールと同じ名前だから変更してくださいというエラーになります。
エラーが出ても焦らずに、エラー文を読んで、英語で分かりづらければ、google翻訳などを使ってみてください。

問題なく上記のコマンドが実行できていれば、下記の必要最低限のファイルが揃ったことになります。
mysite/
├── manage.py
└── mysite
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
ここからは、まず基本的なHello Worldを表示させてみます。

Hello Worldの表示

いきなり、プログラミングを書く前に便利な機能を紹介しておきます。
他のwebフレームワークを触ったことがある方には当たり前ですが、ローカルサーバーを立ち上げる機能があります。
こういった機能はmanage.pyに纏まっているので、普通のpythonを実行するのと同様に、python mysite/manage.py runserverをターミナルで実行してあげるとサーバーが立ち上がります。
そして、http://localhost:8000/ にアクセスすると次のような画面が出るはずです。

いきなり、次に行く前にそれぞれのファイルについて軽く触れておきます。
manage.pyは色々と便利な機能が纏まっているファイルと紹介しました。今後も使っていくので、その都度紹介していきます。
そして、__init__.pyですが、これはpythonモジュールがあることを認識させるためのファイルです。なので、中身自体は空になります。
次にwsgi.pyですが、これはApacheやNGINXなどのWebサーバーとDjangoの仲介役として存在しています。
ブラウザ <-> Apache <-> wsgi.py <-> Django
WSGIは「Web Server Gateway Interface」の略でWebアプリケーションとWebサーバーのやり取りするためのプロトコルです。
最も重要なのが、settings.pyなのですがいきなり全てを説明してもあれなので、今回はデバッグするための設定やタイムゾーンなどの様々な設定を書く場所だと思っておいてください。
このファイルはよく編集するので、何をするかだけは認識しておきましょう。

urls.pyはリクエストのあったURLを受け取って、URL毎にviewを切り替える役割を持っています。
それでは、プログラムを書いていきます。
まず、__init__.pyなどがあるディレクトリに、views.pyを作成します。
その中に下記のコードを書いていきます。views.pyは表示内容とデザインを決めるものです。

from django.http import HttpResponse

def helloworld(request):
  return HttpResponse('Hello World!')

続いて、先程書いた「Hello World!」を表示するためのURL設定を書いていきます。
urls.pyを下記のように変更してください。

from django.contrib import admin
from django.urls import path
from .views import helloworld

urlpatterns = [
    path('admin/', admin.site.urls),
    path('test/', helloworld),
]

まず、urlpatternsの中身に注目すると、’test/’とhelloworldがあるのが分かると思います。これは、どのURLが渡ってきた時に何を表示するかを設定しています。今回は http://localhost:8000/test/ にきた時にhelloworld関数のreturnの値を表示するようにしています。先程書いた関数は、from .views import helloworld で読み込んでいます。サーバーを立ち上げた状態で、上記のURLにアクセスしてみてください。しっかりと「Hello World!」の文字列が表示されているはずです。

今回はdjangoで文字列を表示するところまでやってきました。
次回はCRUD操作をやっていきます。

補足:周辺知識

Functiion Based ViewとClass Based View

ビューを作成していく方法として、大きく分けてFunctiion Based ViewとClass Based Viewに分かれます。「Hello Wolrd!」を表示したのはFunctiion Based Viewです。reactを触ったことがある方はイメージがつきやすいとは思いますが(use stateが実装される前まで)、Class Based Viewは便利な機能が提供されており、細かいプログラミングをしなくても実装することができます。ただし、裏側でどんな処理が動いているかは確認しづらいため、細かい調整はしにくいです。対して、Functiion Based Viewは自身で全てを実装していけるので、手間はかかりますが、全ての処理を把握して実装ができます。
ここに関しては、メリット・デメリットを考えて使用する必要があります。
views.pyとsettings.pyを変更してClass Based Viewを使用してみます。
まずview.pyを変更します。

from django.http import HttpResponse
from django.views.generic import TemplateView

def helloworld(request):
  return HttpResponse('Hello World!')

class HelloWorld(TemplateView):
  template_name = 'hello.html' # htmlファイルの指定(別途作成する必要あり)

htmlファイルを表示する設定を書きましたので、次にhtmlファイルを作成していきます。
どこに作成するかというと、manage.pyと同じ階層に別ディレクトリを作成してその中に作っていきます。構造は下記のようになります。

../
├── db.sqlite3
├── manage.py
├── mysite
│ ├── init.py
│ ├── pycache
│ │ ├── init.cpython-37.pyc
│ │ ├── settings.cpython-37.pyc
│ │ ├── urls.cpython-37.pyc
│ │ ├── views.cpython-37.pyc
│ │ └── wsgi.cpython-37.pyc
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ ├── views.py
│ └── wsgi.py
└── templates
└── hello.html

そして、作成したhello.htmlを変更していきます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>Hello World!</h1>
</body>
</html>​

これで表示するための雛形ができました。
次にdjangoにこのファイルを認識させる必要があります。これはsettings.pyを変更していきます。

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

変更した箇所は、‘DIRS’: [BASE_DIR, ‘templates’]です。
BASE_DIRはmanage.pyがあるディレクトリを指しており、同階層に作成したtemplatesディレクトリを書くことで、django側が認識してくれます。

最後にurls.pyを変更して完了です。

from django.contrib import admin
from django.urls import path
from .views import helloworld, HelloWorld

urlpatterns = [
    path('admin/', admin.site.urls),
    path('test/', helloworld),
    path('test2/', HelloWorld.as_view()),
]

functionとclassの時の大きな違いは、class使用時にはas_view()メソッドを指定してあげる必要があるので注意してください。