最初のDjangoアプリの作成、パート2
このチュートリアルは、 Tutorial 1 が中断したところから始まります。 データベースをセットアップし、最初のモデルを作成して、Djangoの自動生成された管理サイトを簡単に紹介します。
データベースのセットアップ
次に、mysite/settings.py
を開きます。 これは、Django設定を表すモジュールレベルの変数を持つ通常のPythonモジュールです。
デフォルトでは、構成はSQLiteを使用します。 データベースを初めて使用する場合、またはDjangoを試すことに興味がある場合は、これが最も簡単な選択です。 SQLiteはPythonに含まれているため、データベースをサポートするために他に何もインストールする必要はありません。 ただし、最初の実際のプロジェクトを開始するときは、将来のデータベース切り替えの問題を回避するために、PostgreSQLなどのよりスケーラブルなデータベースを使用することをお勧めします。
別のデータベースを使用する場合は、適切なデータベースバインディングをインストールし、:setting: `DATABASES` 'default'
項目の次のキーをデータベース接続に一致するように変更します。設定:
- :setting: `ENGINE ` - また
'django.db.backends.sqlite3'
、'django.db.backends.postgresql'
、'django.db.backends.mysql'
、 また'django.db.backends.oracle'
。 他のバックエンドも利用可能です。 - :setting: `NAME` –データベースの名前。 SQLiteを使用している場合、データベースはコンピューター上のファイルになります。 その場合、:setting: `NAME` は、そのファイルのファイル名を含む完全な絶対パスである必要があります。 デフォルト値の
BASE_DIR / 'db.sqlite3'
は、ファイルをプロジェクトディレクトリに保存します。
データベースとしてSQLiteを使用していない場合は、:setting: `USER` 、:setting:` PASSWORD` 、:setting: `HOST`などの追加設定を追加する必要があります。 詳細については、:setting: `DATABASES` のリファレンスドキュメントを参照してください。
SQLite以外のデータベースの場合
SQLite以外のデータベースを使用している場合は、この時点でデータベースを作成していることを確認してください。 これを行うには、データベースのインタラクティブプロンプト内の「CREATE DATABASE database_name;
」を使用します。
また、mysite/settings.py
で提供されるデータベースユーザーが「データベースの作成」権限を持っていることを確認してください。 これにより、後のチュートリアルで必要になるテストデータベースの自動作成が可能になります。
SQLiteを使用している場合は、事前に何も作成する必要はありません。データベースファイルは、必要なときに自動的に作成されます。
mysite/settings.py
を編集しているときに、:setting: `TIME_ZONE` を自分のタイムゾーンに設定します。
また、ファイルの先頭にある:setting: `INSTALLED_APPS` 設定に注意してください。 これは、このDjangoインスタンスでアクティブ化されるすべてのDjangoアプリケーションの名前を保持します。 アプリは複数のプロジェクトで使用でき、他の人がプロジェクトで使用できるようにパッケージ化して配布できます。
デフォルトでは、:setting: `INSTALLED_APPS` には次のアプリが含まれており、そのすべてにDjangoが付属しています。
- django.contrib.admin –管理サイト。 すぐに使用します。
- django.contrib.auth –認証システム。
- django.contrib.contenttypes –コンテンツタイプのフレームワーク。
- django.contrib.sessions –セッションフレームワーク。
- django.contrib.messages –メッセージングフレームワーク。
- django.contrib.staticfiles –静的ファイルを管理するためのフレームワーク。
これらのアプリケーションは、一般的なケースの便宜のためにデフォルトで含まれています。
ただし、これらのアプリケーションの一部は少なくとも1つのデータベーステーブルを使用するため、使用する前にデータベースにテーブルを作成する必要があります。 これを行うには、次のコマンドを実行します。
:djadmin: `migrate` コマンドは、:setting:` INSTALLED_APPS` 設定を調べ、mysite/settings.py
ファイルのデータベース設定に従って必要なデータベーステーブルを作成します。アプリに同梱されているデータベースの移行(後で説明します)。 適用される移行ごとにメッセージが表示されます。 興味がある場合は、データベースのコマンドラインクライアントを実行し、\dt
(PostgreSQL)、SHOW TABLES;
(MariaDB、MySQL)、.schema
(SQLite)、またはSELECT TABLE_NAME FROM USER_TABLES;
(Oracle)Djangoが作成したテーブルを表示します。
ミニマリストのために
上で述べたように、一般的なケースにはデフォルトのアプリケーションが含まれていますが、すべての人がそれらを必要としているわけではありません。 それらの一部またはすべてが必要ない場合は、:djadmin: `migrate`を実行する前に、:setting:` INSTALLED_APPS` から適切な行をコメントアウトまたは削除してください。 。 :djadmin: `migrate` コマンドは、:setting:` INSTALLED_APPS` 内のアプリの移行のみを実行します。
モデルの作成
次に、モデルを定義します。基本的には、追加のメタデータを使用してデータベースレイアウトを定義します。
哲学
モデルは、データに関する単一の決定的な情報源です。 これには、保存しているデータの重要なフィールドと動作が含まれています。 Djangoは DRY Principle に従います。 目標は、データモデルを一箇所で定義し、そこから自動的に派生させることです。
これには移行が含まれます-たとえば、Ruby On Railsとは異なり、移行は完全にモデルファイルから派生し、基本的にDjangoが現在のモデルに一致するようにデータベーススキーマを更新するためにロールスルーできる履歴です。
投票アプリでは、Question
とChoice
の2つのモデルを作成します。 Question
には質問と発行日があります。 Choice
には、選択したテキストと投票集計の2つのフィールドがあります。 各Choice
は、Question
に関連付けられています。
これらの概念は、Pythonクラスによって表されます。 polls/models.py
ファイルを編集して、次のようにします。
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)
ここで、各モデルは、 django.db.models.Model をサブクラス化するクラスで表されます。 各モデルにはいくつかのクラス変数があり、それぞれがモデルのデータベースフィールドを表します。
各フィールドは、 Field クラスのインスタンスで表されます。たとえば、文字フィールドの場合は CharField 、日時の場合は DateTimeField です。 これにより、各フィールドが保持するデータのタイプがDjangoに通知されます。
各フィールドインスタンスの名前(例: question_text
またはpub_date
)は、マシンフレンドリ形式のフィールド名です。 この値をPythonコードで使用し、データベースはこの値を列名として使用します。
フィールドへのオプションの最初の位置引数を使用して、人間が読める名前を指定できます。 これはDjangoのいくつかの内省的な部分で使用されており、ドキュメントとしても機能します。 このフィールドが指定されていない場合、Djangoは機械可読な名前を使用します。 この例では、Question.pub_date
に対して人間が読める形式の名前のみを定義しました。 このモデルの他のすべてのフィールドでは、フィールドの機械可読名で十分です。
一部の Field クラスには必須の引数があります。 たとえば、 CharField では、 max_length を指定する必要があります。 これは、データベーススキーマだけでなく、すぐにわかるように検証でも使用されます。
フィールドには、さまざまなオプションの引数を指定することもできます。 この場合、votes
のデフォルト値を0に設定しました。
最後に、 ForeignKey を使用して関係が定義されていることに注意してください。 これは、各Choice
が単一のQuestion
に関連していることをDjangoに伝えます。 Djangoは、多対1、多対多、1対1のすべての一般的なデータベース関係をサポートしています。
モデルのアクティブ化
その小さなモデルコードは、Djangoに多くの情報を提供します。 これにより、Djangoは次のことができるようになります。
- このアプリのデータベーススキーマ(
CREATE TABLE
ステートメント)を作成します。 Question
およびChoice
オブジェクトにアクセスするためのPythonデータベースアクセスAPIを作成します。
ただし、最初に、polls
アプリがインストールされていることをプロジェクトに通知する必要があります。
哲学
Djangoアプリは「プラグイン可能」です。特定のDjangoインストールに関連付ける必要がないため、複数のプロジェクトでアプリを使用したり、アプリを配布したりできます。
プロジェクトにアプリを含めるには、:setting: `INSTALLED_APPS` 設定でその構成クラスへの参照を追加する必要があります。 PollsConfig
クラスはpolls/apps.py
ファイルにあるため、点線のパスは'polls.apps.PollsConfig'
です。 mysite/settings.py
ファイルを編集し、その点線のパスを:setting: `INSTALLED_APPS` 設定に追加します。 次のようになります。
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
これで、Djangoはpolls
アプリを含めることを認識しました。 別のコマンドを実行してみましょう:
次のようなものが表示されます。
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
makemigrations
を実行すると、モデルにいくつかの変更を加えた(この場合は新しいモデルを作成した)こと、および変更を[として保存することを希望することをDjangoに伝えます。 X176X]移行。
移行とは、Djangoがモデル(したがってデータベーススキーマ)への変更を保存する方法です。これらはディスク上のファイルです。 必要に応じて、新しいモデルの移行を読むことができます。 それはファイルpolls/migrations/0001_initial.py
です。 心配しないでください。Djangoが作成するたびに読む必要はありませんが、Djangoが物事を変更する方法を手動で調整したい場合に備えて、人間が編集できるように設計されています。
移行を実行し、データベーススキーマを自動的に管理するコマンドがあります。これは:djadmin: `migrate` と呼ばれ、すぐに説明します-しかし、最初に、どのSQLを見てみましょう。その移行が実行されます。 :djadmin: `sqlmigrate` コマンドは、移行名を受け取り、そのSQLを返します。
次のようなものが表示されるはずです(読みやすくするために再フォーマットしました)。
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" (
"id" serial NOT NULL PRIMARY KEY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL,
"question_id" integer NOT NULL
);
ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_c5b4b260_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
次の点に注意してください。
- 正確な出力は、使用しているデータベースによって異なります。 上記の例はPostgreSQL用に生成されています。
- テーブル名は、アプリの名前(
polls
)とモデルの小文字の名前(question
およびchoice
)を組み合わせて自動的に生成されます。 (この動作はオーバーライドできます。) - 主キー(ID)は自動的に追加されます。 (これをオーバーライドすることもできます。)
- 慣例により、Djangoは外部キーフィールド名に
"_id"
を追加します。 (はい、これをオーバーライドすることもできます。) - 外部キーの関係は、
FOREIGN KEY
制約によって明示的になります。DEFERRABLE
の部品については心配しないでください。 トランザクションが終了するまで外部キーを強制しないようにPostgreSQLに指示しています。 - 使用しているデータベースに合わせて調整されているため、
auto_increment
(MySQL)、serial
(PostgreSQL)、integer primary key autoincrement
(SQLite)などのデータベース固有のフィールドタイプが処理されます。自動的にあなたのために。 フィールド名の引用についても同じことが言えます。たとえば、二重引用符または一重引用符を使用します。 - :djadmin: `sqlmigrate` コマンドは、実際にはデータベースで移行を実行しません。代わりに、SQL Djangoが必要と考えるものを確認できるように、画面に出力します。 Djangoが何をするのかを確認したり、変更のためにSQLスクリプトを必要とするデータベース管理者がいる場合に役立ちます。
興味があれば、実行することもできます :djadmin: `pythonmanage.pyチェック ` ; これにより、移行を行ったりデータベースに触れたりすることなく、プロジェクトの問題をチェックします。
ここで、:djadmin: `migrate` を再度実行して、データベースにこれらのモデルテーブルを作成します。
:djadmin: `migrate` コマンドは、適用されていないすべての移行を取得し(Djangoは、データベース内のdjango_migrations
という特別なテーブルを使用して適用された移行を追跡します)、それらを実行します。データベース-基本的に、モデルに加えた変更をデータベースのスキーマと同期します。
移行は非常に強力であり、プロジェクトの開発中に、データベースやテーブルを削除して新しいものを作成することなく、時間の経過とともにモデルを変更できます。これは、データを失うことなく、データベースをライブでアップグレードすることを専門としています。 これらについては、チュートリアルの後半で詳しく説明しますが、今のところ、モデルを変更するための3つのステップのガイドを覚えておいてください。
- モデルを変更します(
models.py
内)。 - 走る :djadmin: `python manage.py makemigrations ` それらの変更の移行を作成するには
- 走る :djadmin: `python manage.pymigrate ` それらの変更をデータベースに適用します。
移行を行って適用するための個別のコマンドがある理由は、バージョン管理システムに移行をコミットして、アプリに同梱するためです。 開発が容易になるだけでなく、他の開発者や本番環境でも使用できます。
manage.py
ユーティリティでできることの詳細については、 django-adminのドキュメントをお読みください。
APIで遊ぶ
それでは、インタラクティブなPythonシェルに飛び乗って、Djangoが提供する無料のAPIを試してみましょう。 Pythonシェルを呼び出すには、次のコマンドを使用します。
manage.py
は DJANGO_SETTINGS_MODULE 環境変数を設定し、Djangoにmysite/settings.py
ファイル。
シェルに入ったら、データベースAPI を調べます。
>>> from polls.models import Choice, Question # Import the model classes we just wrote.
# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>
# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
# Save the object into the database. You have to call save() explicitly.
>>> q.save()
# Now it has an ID.
>>> q.id
1
# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()
# objects.all() displays all the questions in the database.
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
ちょっと待って。 <Question: Question object (1)>
は、このオブジェクトの有用な表現ではありません。 Question
モデル(polls/models.py
ファイル内)を編集し、 __ str __()メソッドをQuestion
と [の両方に追加して修正しましょう。 X135X]:
from django.db import models
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text
__ str __()メソッドをモデルに追加することは重要です。これは、インタラクティブプロンプトを処理するときの利便性のためだけでなく、オブジェクトの表現がDjangoの自動生成された管理全体で使用されるためです。
このモデルにカスタムメソッドも追加しましょう。
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
Pythonの標準datetime
モジュールと django.utils.timezone のDjangoのタイムゾーン関連ユーティリティを参照するために、import datetime
とfrom django.utils import timezone
が追加されていることに注意してください。それぞれ。 Pythonでのタイムゾーンの処理に慣れていない場合は、タイムゾーンサポートドキュメントで詳細を確認できます。
これらの変更を保存し、python manage.py shell
を再度実行して、新しいPythonインタラクティブシェルを開始します。
>>> from polls.models import Choice, Question
# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>
# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>
# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)
# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>
# Create three choices.
>>> 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)
# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>
# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
モデルリレーションの詳細については、関連オブジェクトへのアクセスを参照してください。 二重アンダースコアを使用してAPIを介してフィールドルックアップを実行する方法の詳細については、フィールドルックアップを参照してください。 データベースAPIの詳細については、データベースAPIリファレンスを参照してください。
Django管理者の紹介
哲学
スタッフやクライアントがコンテンツを追加、変更、削除するための管理サイトを生成することは、多くの創造性を必要としない退屈な作業です。 そのため、Djangoはモデルの管理インターフェースの作成を完全に自動化します。
Djangoはニュースルーム環境で作成され、「コンテンツ発行者」と「公開」サイトが非常に明確に区別されています。 サイト管理者はこのシステムを使用してニュース記事、イベント、スポーツスコアなどを追加し、そのコンテンツは公開サイトに表示されます。 Djangoは、サイト管理者がコンテンツを編集するための統一されたインターフェースを作成するという問題を解決します。
管理者は、サイト訪問者が使用することを意図したものではありません。 サイト管理者向けです。
管理者ユーザーの作成
まず、管理サイトにログインできるユーザーを作成する必要があります。 次のコマンドを実行します。
希望のユーザー名を入力し、Enterキーを押します。
Username: admin
次に、希望のメールアドレスの入力を求められます。
Email address: [email protected]
最後のステップは、パスワードを入力することです。 パスワードの入力を2回求められます。2回目は1回目の確認です。
Password: **********
Password (again): *********
Superuser created successfully.
開発サーバーを起動します
Django管理サイトはデフォルトでアクティブ化されています。 開発サーバーを起動して調べてみましょう。
サーバーが実行されていない場合は、次のように起動します。
次に、Webブラウザーを開き、ローカルドメインの「/ admin /」に移動します(例: http://127.0.0.1:8000/admin/)。 管理者のログイン画面が表示されます。
Django admin login screen translation はデフォルトでオンになっているため、:setting: `LANGUAGE_CODE` を設定すると、ログイン画面が指定された言語で表示されます(Djangoに適切な翻訳がある場合)。
管理サイトに入る
ここで、前の手順で作成したスーパーユーザーアカウントでログインしてみてください。 Django管理者インデックスページが表示されます。
Django admin index page グループとユーザーという、編集可能なコンテンツのいくつかのタイプが表示されます。 これらは、Djangoによって出荷された認証フレームワークである django.contrib.auth によって提供されます。
管理者で投票アプリを変更可能にする
しかし、私たちの投票アプリはどこにありますか? 管理者インデックスページには表示されません。
もう1つ行う必要があるのは、Question
オブジェクトに管理インターフェイスがあることを管理者に通知する必要があることです。 これを行うには、polls/admin.py
ファイルを開き、次のように編集します。
from django.contrib import admin
from .models import Question
admin.site.register(Question)
無料の管理機能を調べる
Question
を登録したので、Djangoはそれが管理者インデックスページに表示される必要があることを認識しています。
Django admin index page, now with polls displayed 「質問」をクリックします。 これで、質問の「変更リスト」ページが表示されます。 このページには、データベース内のすべての質問が表示され、質問を1つ選択して変更できます。 「どうしたの?」があります。 以前に作成した質問:
Polls change list page 「どうしたの?」をクリックします。 それを編集するための質問:
Editing form for question object ここで注意すべきこと:
- フォームは
Question
モデルから自動的に生成されます。 - さまざまなモデルフィールドタイプ( DateTimeField 、 CharField )は、適切なHTML入力ウィジェットに対応しています。 各タイプのフィールドは、Django管理者に自分自身を表示する方法を知っています。
- 各 DateTimeField は、無料のJavaScriptショートカットを取得します。 日付には「今日」のショートカットとカレンダーのポップアップが表示され、時刻には「今」のショートカットと一般的に入力される時刻を一覧表示する便利なポップアップが表示されます。
ページの下部には、いくつかのオプションがあります。
- 保存–変更を保存し、このタイプのオブジェクトの変更リストページに戻ります。
- 保存して編集を続行–変更を保存し、このオブジェクトの管理ページを再読み込みします。
- 別のオブジェクトを保存して追加–変更を保存し、このタイプのオブジェクトの新しい空白のフォームをロードします。
- 削除–削除確認ページを表示します。
「公開日」の値がチュートリアル1 で質問を作成した時刻と一致しない場合は、:setting: `TIME_ZONE`に正しい値を設定し忘れたことを意味している可能性があります。 設定。 変更してページをリロードし、正しい値が表示されることを確認してください。
「今日」と「今」のショートカットをクリックして、「公開日」を変更します。 次に、[保存して編集を続行]をクリックします。 次に、右上の「履歴」をクリックします。 Django管理者を介してこのオブジェクトに加えられたすべての変更と、変更を行った人のタイムスタンプとユーザー名を一覧表示するページが表示されます。
History page for question object モデルAPIに慣れ、管理サイトに慣れたら、このチュートリアルのパート3 を読んで、投票アプリにビューを追加する方法を確認してください。