diadia

興味があることをやってみる。自分のメモを残しておきます。

django 日記の作り方

日記アプリを作る

日記タイトル、日付、日記の内容を表示するアプリケーションの作り方。
これはdjango初学者にとってイメージしづらいdjangoの使い方をイメージしてもらいたくて書きました。

 

環境構築

windows,macを使う場合いずれにしても、anacondaをインストールしてから作ることをおすすめする。

conda create -n django36 python==36

django36は環境名です。この環境にdjangoやpython3.6を入れることになります。

 

diaryディレクトリを作成する

mkdir diary
cd diary
conda activate django36    #windowsの場合
source activate django36   #macの場合

 

djangoを環境に入れる

 

pip install django
pip freeze    #djangoをインストールできていればコマンド入力の結果にdjangoと表示されます

 

djangoでアプリケーション作成を始める

以下のコマンドを打つと、diaryディレクトリにディレクトリ、ファイルが自動的に作成されます。

django-admin startproject diary .

 

投稿した日記を表示する仕組み(contentsアプリ)を作成する

python manage.py startapp contents

 

必要な編集

models.py,urls.pyとviews.pyを編集していく。models.pyでは表示したい内容の型を定め、urls.pyではURL入力すると表示を担当するviews.pyにつなげる設定を行う。views.pyでは表示を今回は担当する。

1.diary/urls.pyを編集

diary/urls.py(編集前)...

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

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

python manage.py startproject diary .と入力すると以上の内容のurls.pyが自動生成される。このファイルにはpath("", include(contents.urls)), を挿入する。

diary/urls.py(編集後)...

from django.contrib import admin
from django.urls import path, include  # includeも追加する
import contents.urls


urlpatterns = [
    path('admin/', admin.site.urls),
    path('contents/', include(contents.urls)),
]

2.contents/urls.pyを編集

contentsにurls.pyが予め作ってあるわけではないので、urls.pyを作成する。例えばターミナルでurls.pyを作成する場合以下のコマンドを入力する。

cd contents
touch urls.py
contents/urls.py...

from django.urls import path
from contents.views import lists, detail

app_name = "contents"

urlpatterns = [
    path('', lists, name="lists"),
    path('<int:pk>', detail, name="detail"),
]

3.contents/models.pyを編集

以下に定める内容がウェブで表示される内容となる。表示したいものを増やしたければ追加すれば良い。

contents/models.py...

from django.db import models

class Content(models.Model):
    title = models.CharField(max_length=30)
    text  = models.TextField()
    date  = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return self.title

4.contents/views.pyを編集

編集前は以下のようになっている。

contents/views.py(編集前)...

from django.shortcuts import render

# Create your views here.

以下のように編集すれば良い。

contents/views.py(編集後)...

from django.shortcuts import render
from django.http import HttpResponse

from contents.models import Content


def lists(request):
    return HttpResponse("this is test, これはテストです")


def detail(request, pk):
    detail_object = Content.objects.get(id=pk)
    context = {}
    context["object"] = detail_object   #辞書型データの扱い方法を調べてみてください
    return render(request, "contents/detail.html", context)

5.マイグレーションする

以下のコマンドでマイグレーションする。マイグレーションするときには、settings.pyのINSTALLED_APPSのリストにアプリを前もって追加しなければならない。
今回の場合はcontentsがアプリなので以下のように追加できれば良い。

5-1.INSTALLED_APPSにアプリを追加
diary/settings.py(編集後)...

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'contents',    # これを追加する
]
5-2.マイグレーションの実行

5-2-1.マイグレーションのコマンドを実行

python manage.py makemigrations

このコマンドの結果がこんな感じなら大丈夫です。

(コマンドの結果)
Migrations for 'contents':
  contents/migrations/0001_initial.py
    - Create model Content

5-2-2.migrateする

python manage.py migrate

このコマンドの結果がこんな感じなら大丈夫です。

Operations to perform:
  Apply all migrations: admin, auth, contents, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying contents.0001_initial... OK
  Applying sessions.0001_initial... OK

 

内容を登録する

内容とは今回の場合は日記です。title, text, dateを入力することが内容を登録することです。
内容の登録方法は管理者ページ(admin)から行う方法、内容登録画面を作成して内容登録する方法があります。他にもShellからの方法、APIからの方法といろいろありますが簡単に構築できる方法は上記の2つです。今回は管理者ページから内容を登録します。

管理者ページとは

runserverした状態で、ブラウザから"localhost:8000/admin"と入力すると表示されるページを管理者ページと言います。これは今作成しているウェブアプリケーションを運営管理する機能のものです。ここで運営管理するユーザーの設定を変えたり、今回で言えば登録した日記の内容を変えたり、タイトルを変えたりするときに使います。今回はここから日記の内容を作成する。

管理者ページには管理者権限があるユーザが必要

localhost:8000/adminとするとログイン画面が表示される。管理者権限を持つユーザでしかログインできない。

スーパーユーザーの作成する
python manage.py createsuperuser

入力するとusernameの入力があります。適当にusernameを決めて入力してください。
その次にE-mail addressを入力を要求されます。ここは入力しても入力しなくても大丈夫です。
次にpasswordの入力です。passwordは一度入力し、確認のために更に入力を求められます。passwordの入力じには自分がうったpasswordが画面には表示されませんが、心配しなくても入力できていますので安心してください。。

(コマンドの結果)
Superuser created successfully.

このように表示されればスーパーユーザが作成されました。このスーパーユーザを使ってadminページにアクセスします。

内容を登録する

Contentsを選んで内容を登録します。2,3個作ってみてください。これで準備が整いました。

 

ページが表示されるか確認してみる

コンソール画面でpython manege.py runserver を行った上で、試しに'localhost:8000/contents'そして'localhost:8000/contents/1','localhost:8000/contents/2'とブラウザに打ち込んでみてください。

localhost:8000/contentsと入力した場合には、

this is test, これはテストです

と表示されるはずです。一方、'localhost:8000/contents/1','localhost:8000/contents/2'と入力した場合には以下のようなエラーが書かれたページが表示されます。

TemplateDoesNotExist at /contents/1

views.pyで使ったrenderはテンプレートを必要としているのにもかかわらず、テンプレートを準備していないことに起因するエラーです。render()はテンプレートが必要なものだと覚えておいてください。

 

テンプレートを作成する

contents/templates/contents以下にhome.html, detail.htmlを作成します。このhome.html, detail.htmlをテンプレートと呼びます。

cd contents   # contentsディレクトリに移動
mkdir templates   # templatesディレクトリを作成
cd templates    # templatesディレクトリに移動
touch home.html   # home.html を作成
touch detail.html   # detail.html を作成

 

detail.htmlのテンプレートを作成する

上記の処理で作成したdetail.htmlに編集を加えていきます。表示するためだけの必要最低限のことだけ編集します。なおこの段階でテンプレート自体は存在するので、'localhost:8000/contents/1'または'localhost:8000/contents/2'とアクセスしてもエラーは出なくなります。

<h1>{{ object.title }}</h1>
<br />
{{ object.text }}

再びアクセスしてみる

'localhost:8000/contents/1'または'localhost:8000/contents/2'でアクセスしてみてください。日記のタイトルと内容が表示されたと思います。