【Python】公式サイトでdjangoを学習する その2

今回は前回に引き続き、djangoの公式サイトにある「はじめての Django アプリ作成、その 2」を試してみました。

Database の設定


mysite/settings.pyをエディターで開きます。

デフォルトでは、SQLiteが設定されていますが、本番の環境ではデータベースの移行を避けるため、PostgreSQL などのよりスケーラブルなデータベースを使った方が良いと公式文章にあります。

他のデータベースを使用する際は、適切なデータベースのバインディングをインストールして、下記の設定を変更する必要があるようです。

デフォルトの状態は次の通りです。

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

ENGINEの記述を必要に応じて書き換えます。

PostgreSQLの場合

django.db.backends.postgresql

mysqlの場合

django.db.backends.mysql

oracleの場合

django.db.backends.oracle

NAMEは、データベースの名前で、
SQLite を使用している場合、
データベース(db.sqlite3)はコンピュータ上のファイルになります。
その場合、NAME には、そのファイルのファイル名を含んだ絶対パスを指定する必要があります。

公式からの引用

SQLite 以外のデータベースの場合

もし SQLite 以外を使っている場合、 database を今のうちに作っておいてください。 “CREATEDATABASE database_name;” とデータベースのインタラクティブプロンプトで実行してください。

mysite/settings.py のデータベースユーザに 「データベース作成」の権限があることを確認します。これは、この後のチュートリアルの テストDB を自動作成することができます。

SQLite を使っている場合は、前もってすることはありません。必要であればデータベースファイルが自動で生成されます。

TIME_ZONEを自分のタイムゾーンに変更する。


デフォルトでは下記のようになっています。

TIME_ZONE = 'UTC'

データベースのテーブルを次のコマンドで自動で作成します。


$ python manage.py migrate

モデルの作成


モデルとはデータベースのレイアウトとそれに付随するメタデータである。

from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

モデルを有効にする


settings.pyに、polls.apps.PollsConfigを追記します。

# Application definition

INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

コマンドを実行して、モデルの作成・変更を伝えます。


$ python manage.py makemigrations polls

次のように表示されます。

Migrations for 'polls':

  polls/migrations/0001_initial.py

    - Create model Choice

    - Create model Question

    - Add field question to choice

 

テーブルの確認をする時のコマンド


次のコマンドを実行するとテーブルの設定を確認できます。

$ python manage.py sqlmigrate polls 0001

モデルの作成・変更後は、テーブルをもう一度migrateする


$ python manage.py migrate

公式サイトからの引用

migrate コマンドは INSTALLED_APPS の設定を参照するとともに、 mysite/settings.py ファイルのデータベース設定に従って必要なすべてのデータベースのテーブルを作成します。このデータベースマイグレーションはアプリと共に配布されます (これらについては後ほどカバーします)。マイグレーションを実施するたび、メッセージを見ることになります。

API で遊んでみる(対話シェルを実施)


次のコマンドを打つと、Pythonと対話する形式でプログラムを実行できます。

$ python manage.py shell

プログラムを読み慣れていない方は、いまはシェルの対話部分を飛ばしても良いと思います。

(InteractiveConsole)

>>> from polls.models import Choice, Question

>>> Question.objects.all()

<QuerySet []>

>>> from django.utils import timezone

>>> q = Question(question_text="What's new?", pub_date=timezone.now())

>>> q.save()

>>> q.id

1

>>> q.question_text

"What's new?"

>>> q.pub_date

datetime.datetime(2018, 10, 18, 9, 53, 45, 771384, tzinfo=<UTC>)

>>> q.qestion_text = "What's up?"

>>> q.save()

>>> Question.objects.all()

<QuerySet [<Question: Question object (1)>]>

問題点

<QuerySet [<Question: Question object (1)>]>としか答えないので、次のようにプログラムを書き換えます。

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

# Create your models here.


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
    	return self.question_text

    def  was_published_recently(self):
    	return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
    	


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
    	return self.choice_text

シェルの終了

変更したので、exit()で一度対話シェルを終了して、再度$ python manage.py shellを実行します。

対話シェル改良後


公式サイトでは、次のような対話シェルがなされています。

(InteractiveConsole)

>>> from polls.models import Choice, Question

>>> Question.objects.all()

<QuerySet [<Question: What's new?>]>

>>> Question.objects.filter(id=1)

<QuerySet [<Question: What's new?>]>

>>> Question.objects.filter(question_text__startswith='What')

<QuerySet [<Question: What's new?>]>

>>> from django.utils import timezone

>>> current_year = timezone.now().year

>>> Question.objects.get(pub_date__year=current_year)

<Question: What's new?>

>>> Question.objects.get(id=2)

>>> Question.objects.get(pk=1)

<Question: What's new?>

>>> q = Question.objects.get(pk=1)

>>> q.was_published_recently()

True

>>> q = Question.objects.get(pk=1)

>>> q.choice_set.all()

<QuerySet []>

>>> q.choice_set.create(choice_text='Not much', votes=0)

<Choice: Not much>

>>> q.choice_set.create(choice_text='The sky', votes=0)

<Choice: The sky>

>>> c = q.Choice_set.create(choice_text='Just hacking again', votes=0)

Traceback (most recent call last):

  File "<console>", line 1, in <module>

AttributeError: 'Question' object has no attribute 'Choice_set'

>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

>>> c.question

<Question: What's new?>

>>> q.choice_set.all()

<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

>>> q.choice_set.count()

3

>>> Choice.objects.filter(question__pub_date__year=current_year)

<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')

>>> c.delete()

管理ユーザーを作成する


次のコマンドを打ち、管理者のユーザー名、メールアドレス、パスワードを設定します。

$ python manage.py createsuperuser

Username :      

Email address:

Password: 

Password (again): 

Superuser created successfully.

開発サーバーの起動


Django adminサイトはデフォルトで有効化される。

サーバーがもし、起動していなかったら次のコマンドで起動させます。

$ python manage.py runserver

ブラウザで管理画面を開く


http://127.0.0.1:8000/admin/

kanrigamen

Poll アプリを admin 上で編集できるようにする


admin.pyに記述する。

from django.contrib import admin

# Register your models here.
from .models import Question

admin.site.register(Question)

次のような画面が表示されるようになる。
Questionモデルから自動的にフォームが作成されます。

django

以上です。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください