Django チュートリアル Part2 -- モデルからテーブルを作ってシェルモードでテーブルの中身を移動
前回
前回の記事で Docker Compose で環境構築して
Django チュートリアルの最初までやった
今回はその続きをやる
パート2
https://docs.djangoproject.com/en/4.0/intro/tutorial02/
モデルを作る
https://docs.djangoproject.com/en/4.0/intro/tutorial02/#creating-models
docker-compose run web python manage.py migrate
これでDBの初期化をする必要がある
次にDBテーブルを作るためのモデルのファイルを書きます.
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)
質問とそれに関連する 選択肢のデータベースを作る
これ Blitz のルールでも見たぞ
モデルを読み込んで有効化する
https://docs.djangoproject.com/en/4.0/intro/tutorial02/#activating-models
これを入力するためには settings.py に書き込む必要がある
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
polls/の一つ上のディレクトリの settings.py の
INSTALLED_APPS に 'polls.apps.PollsConfig',
を追加する
makemigrations で初期化の準備ファイルを作る
By running makemigrations, you’re telling Django that you’ve made some changes to your models (in this case, you’ve made new ones) and that you’d like the changes to be stored as a migration.
docker-compose run web \
python manage.py makemigrations polls
polls から移行する
docker-compose run web \
python manage.py makemigrations polls
Creating dockerdjango_web_run ... done
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
初期化の準備ファイルができた
sqlmigrate で makemigrations で作った init ファイルを
移行する
docker-compose run web \
python manage.py sqlmigrate polls 0001
[+] Running 1/0
⠿ Container dockerdjango-db-1 Running 0.0s
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" ("id" bigserial 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" bigserial NOT NULL PRIMARY KEY, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" bigint 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;
これで sql を発行する
migrate で sql を実行する
docker-compose run web \
python manage.py migrate
これを実行して
docker-compose run web \
python manage.py migrate
[+] Running 1/0
⠿ Container dockerdjango-db-1 Running 0.0s
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying polls.0001_initial... OK
反映された
シェルでモードでテーブルの中身を確認する
https://docs.djangoproject.com/en/4.0/intro/tutorial02/#playing-with-the-api
docker-compose run web \
python manage.py shell
これを実行すると
docker-compose run web \
python manage.py shell
[+] Running 1/0
⠿ Container dockerdjango-db-1 Running 0.0s
Python 3.10.0 (default, Oct 16 2021, 10:05:15) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
少なくともモードになる
>>> from polls.models import Choice, Question
Question.objects.all()
<QuerySet []>
作った投票アプリのモデルから、質問と選択肢を持ってきて
全部を引っ張ってくると、何も入っていない
timezone の形でデータを入れて、保存して Question.object.all で中身を見る。
from django.utils import timezone
timezone のライブラリを持ってきて
q = Question(question_text="What's new?", pub_date=timezone.now())
qという一時現在変数に質問文のテキストと、作成日の日付にの日付を入れる
>>> q
<Question: Question object (None)>
>>> q.question_text
"What's new?"
>>> q.id
>>>
中身のカラムを指定するとみれる、今はidがないが
>>> q.save()
>>> q.id
1
保存するとidが出る
q.pub_date
datetime.datetime(2021, 12, 19, 13, 17, 26, 609289, tzinfo=<UTC>)
datetime で保存されている
>>> q.objects.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python3.10/site-packages/django/db/models/manager.py", line 179, in __get__
raise AttributeError("Manager isn't accessible via %s instances" % cls.__name__)
AttributeError: Manager isn't accessible via Question instances
中身を全て見ることはこの段階ではできない
>>> q.save()
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
しかしこれだと中身が出てこないので、
もう少し工夫する必要がある
str を追加して text の中身を見えるようにする
docker-compose run web \
python manage.py shell
[+] Running 1/0
⠿ Container dockerdjango-db-1 Running 0.0s
Python 3.10.0 (default, Oct 16 2021, 10:05:15) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> Question.objects.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'Question' is not defined
>>> from polls.models import Choice, Question
>>> Question.objects.all()
<QuerySet [<Question: How Are You?>]>
質問の中身を見る時に、オブジェクトの中身のテキストが表示されるようになった
条件で求める
>>> Question.objects.filter(id=1)
<QuerySet [<Question: How Are You?>]>
>>> Question.objects.filter(id=2)
<QuerySet []>
>>> Question.objects.filter(question_text__startswith='H')
<QuerySet [<Question: How Are You?>]>
フィルター、で始まる、
で検索することができるし
>>> Question.objects.get(id=1)
<Question: How Are You?>
>>> Question.objects.get(id=0)
...
polls.models.Question.DoesNotExist: Question matching query does not exist.
>>> Question.objects.get(pk=1)
<Question: How Are You?>
id, primary key で指定することもできる
Question id 1 下に .create(column='hoge') でChoice を作る
>>> q = Question.objects.get(pk=1)
>>> q.choice_set.all()
<QuerySet []>
子供テーブルは parent.children_set.all()
で見れるらしい.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>]>
今後 .create(column_name='text', column_name2=0)
のようにつけると追加できる!
.count() で数える
>>> q.choice_set.count()
1
.count で数を数えられて
.delete() で削除する
>>> c = q.choice_set.filter(choice_text__startswith='Not')
>>> c
<QuerySet [<Choice: Not much>]>
>>> c.delete
<bound method QuerySet.delete of <QuerySet [<Choice: Not much>]>>
>>> c.delete()
(1, {'polls.Choice': 1})
>>> q.choice_set.all()
<QuerySet []>
>>>
取得して .delete() 投入と削除できた!
最近投稿されたかどうかの関数を作る
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
現時点から1日経っていない投稿かを判断する
これからやること
https://docs.djangoproject.com/en/4.0/intro/tutorial02/#introducing-the-django-admin
admin を作る
Reference
この問題について(Django チュートリアル Part2 -- モデルからテーブルを作ってシェルモードでテーブルの中身を移動), 我々は、より多くの情報をここで見つけました
https://dev.to/kaede_io/django-tutorial-part2-3d2c
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
docker-compose run web 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)
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
By running makemigrations, you’re telling Django that you’ve made some changes to your models (in this case, you’ve made new ones) and that you’d like the changes to be stored as a migration.
docker-compose run web \
python manage.py makemigrations polls
docker-compose run web \
python manage.py makemigrations polls
Creating dockerdjango_web_run ... done
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
docker-compose run web \
python manage.py sqlmigrate polls 0001
[+] Running 1/0
⠿ Container dockerdjango-db-1 Running 0.0s
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" ("id" bigserial 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" bigserial NOT NULL PRIMARY KEY, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" bigint 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;
docker-compose run web \
python manage.py migrate
docker-compose run web \
python manage.py migrate
[+] Running 1/0
⠿ Container dockerdjango-db-1 Running 0.0s
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying polls.0001_initial... OK
docker-compose run web \
python manage.py shell
docker-compose run web \
python manage.py shell
[+] Running 1/0
⠿ Container dockerdjango-db-1 Running 0.0s
Python 3.10.0 (default, Oct 16 2021, 10:05:15) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
(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
<Question: Question object (None)>
>>> q.question_text
"What's new?"
>>> q.id
>>>
>>> q.save()
>>> q.id
1
q.pub_date
datetime.datetime(2021, 12, 19, 13, 17, 26, 609289, tzinfo=<UTC>)
>>> q.objects.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python3.10/site-packages/django/db/models/manager.py", line 179, in __get__
raise AttributeError("Manager isn't accessible via %s instances" % cls.__name__)
AttributeError: Manager isn't accessible via Question instances
>>> q.save()
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
docker-compose run web \
python manage.py shell
[+] Running 1/0
⠿ Container dockerdjango-db-1 Running 0.0s
Python 3.10.0 (default, Oct 16 2021, 10:05:15) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> Question.objects.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'Question' is not defined
>>> from polls.models import Choice, Question
>>> Question.objects.all()
<QuerySet [<Question: How Are You?>]>
>>> Question.objects.filter(id=1)
<QuerySet [<Question: How Are You?>]>
>>> Question.objects.filter(id=2)
<QuerySet []>
>>> Question.objects.filter(question_text__startswith='H')
<QuerySet [<Question: How Are You?>]>
>>> Question.objects.get(id=1)
<Question: How Are You?>
>>> Question.objects.get(id=0)
...
polls.models.Question.DoesNotExist: Question matching query does not exist.
>>> Question.objects.get(pk=1)
<Question: How Are You?>
>>> 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.all()
<QuerySet [<Choice: Not much>]>
>>> q.choice_set.count()
1
>>> c = q.choice_set.filter(choice_text__startswith='Not')
>>> c
<QuerySet [<Choice: Not much>]>
>>> c.delete
<bound method QuerySet.delete of <QuerySet [<Choice: Not much>]>>
>>> c.delete()
(1, {'polls.Choice': 1})
>>> q.choice_set.all()
<QuerySet []>
>>>
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
Reference
この問題について(Django チュートリアル Part2 -- モデルからテーブルを作ってシェルモードでテーブルの中身を移動), 我々は、より多くの情報をここで見つけました https://dev.to/kaede_io/django-tutorial-part2-3d2cテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol