Python独学ならTech-Joho TOP > django入門/ > Django 1.11 モデルの追加とマイグレーション
Djangoでモデルを追加する
こちらのDjango公式チュートリアル (バージョン1.11用)をやってみます。
https://docs.djangoproject.com/ja/1.11/intro/tutorial02/
そのままやっても意味がないので、モデル名を変えてみます。
初心者の方は、両方を見比べることで、どのようにモデルを作ればいいのかがわかると思います。
基本的に、こちらの記事の続きです。
Windows 10 でDjango入門
設定
アプリ名は
“djangoTestApp”
だとします。
データベース名は
“django_test_app”
です。
データベース設定
mysqlにログインして
CREATE DATABASE django_test_app;
djangoTestApp2/settings.py
DATABASES = {
'default': {
#'ENGINE': 'django.db.backends.sqlite3',# もともとの設定
'ENGINE': 'django.db.backends.mysql',
#'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # もともとの設定
'NAME': 'django_test_app',
'USER': 'xxxx',
'PASSWORD': 'xxxx',
'HOST': '127.0.0.1'
}
}
上記のような書き方は、settings.pyの一部を表す。
例えば、上の例は76行目付近だった。
settings.pyを開いて、DATABASES等で検索して該当箇所まで移動して修正すること。
もしくは、設定ファイルを別に用意して使う
参考
https://docs.djangoproject.com/ja/1.11/ref/databases/#mysql-notes
djangoで使えるmysqlのアダプタはいくつかある
python3で推奨されているmysqlclient にする
参考
コンソール
> pip3 install mysqlclient
コンソールというのは、windows power shellや、コマンドプロンプトのこと
>の行の内容を入力する
ついでに、タイムゾーンと言語設定
djangoTestApp/settings.py
#LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ja-jp'
#TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Tokyo'
タイムゾーンのリスト
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
マイグレーション実行の方法
コンソール
> python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, 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 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 sessions.0001_initial... OK
こんな感じの表示が出たら成功
モデル作成
もともとのチュートリアルは投票アプリケーションらしく、
Question(投票項目)とChoice(選択肢)という2つのモデルを定義する
同じ例ではつまらないので、はてなブックマークのようなソーシャルブックマークサービスを想定する
Article(記事)とBookmark(ブックマーク)
ブックマークにはstar(スター)をつける
アプリ作成からやりなおす
> python manage.py startapp bookmaker
bookmaker/urls.py
をつくり
djangoTestApp/urls.pyを修正する
仮のER図はこちらです。
djangoのDB変更は3ステップ
- models.pyを変更
- python manage.py makemigrations でマイグレーションファイルを作成
- python manage.py migrate でマイグレーション実行
djangoTestApp/models.py
rom django.db import models
class Article(models.Model):
"""記事"""
summary = models.CharField(max_length=200)
published = models.DateTimeField('date published')
class Bookmark(models.Model):
"""ブックマーク"""
article = models.ForeignKey(Article, on_delete=models.CASCADE)
comment = models.CharField(max_length=200)
stars = models.IntegerField(default=0)
djangoTestApp/settings.py
INSTALLED_APPS = [
'bookmarker.apps.BookmarkerConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
モデルを確認して、マイグレーションファイルを作成する
> python manage.py makemigrations bookmarker
Migrations for 'bookmarker':
bookmarker\migrations\0001_initial.py
- Create model Article
- Create model Bookmark
0001というマイグレーションができた
できたマイグレーションの内容を確認
> python manage.py sqlmigrate bookmarker 0001
BEGIN;
--
-- Create model Article
--
CREATE TABLE `bookmarker_article` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `summary` varchar(200) NOT NULL, `published` datetime(6) NOT NULL);
--
-- Create model Bookmark
--
CREATE TABLE `bookmarker_bookmark` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `comment` varchar(200) NOT NULL, `stars` integer NOT NULL, `article_id` integer NOT NULL);
ALTER TABLE `bookmarker_bookmark` ADD CONSTRAINT `bookmarker_bookmark_article_id_8c3fd859_fk_bookmarker_article_id` FOREIGN KEY (`article_id`) REFERENCES `bookmarker_article` (`id`);
COMMIT;
CREATE TABLEのSQL文がふたつ
> python manage.py migrate
実行された
Shellでモデルの使い方の確認
シェル起動
> python manage.py shell
いろいろなメソッドを使ってみる
>>> from bookmarker.models import Article
>>> Article.objects.all()
>>>
>>> from django.utils import timezone
>>> a = Article(summary='This is the first article.', published=timezone.now())
>>> a.save()
>>> a.id
1
>>> a.summary
'This is the first article.'
>>> a.published
datetime.datetime(2017, 10, 11, 4, 11, 25, 212888, tzinfo=)
>>> Article.objects.all()
]>
モデル一覧を見てみたが、(Article.objects.all())中身がぜんぜんわからないので、表示設定をする
モデルに表示設定など追加
models.py
import datetime
from django.db import models
from django.utils import timezone
class Article(models.Model):
"""記事"""
summary = models.CharField(max_length=200)
published = models.DateTimeField('date published')
def __str__(self):
return self.summary
def was_published_recently(self):
return self.published >= timezone.now() - datetime.timedelta(days=1)
class Bookmark(models.Model):
"""ブックマーク"""
article = models.ForeignKey(Article, on_delete=models.CASCADE)
comment = models.CharField(max_length=200)
stars = models.IntegerField(default=0)
def __str__(self):
return self.comment
__str__というメソッドをそれぞれ追加した。
もう一回シェルを立ち上げて確認する
> python manage.py shell
モデルのいろいろな使い方を確認してみる
検索、取得、作成、削除など..
>>> from bookmarker.models import Article
>>> Article.objects.all()
]>
>>> Article.objects.filter(id=1)
]>
>>> Article.objects.filter(summary__startswith='This')
]>
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Article.objects.get(published__year=current_year)
>>> Article.objects.filter(id=2)
>>> Article.objects.get(id=2)
Traceback (most recent call last):
File "", line 1, in
略
self.model._meta.object_name
bookmarker.models.DoesNotExist: Article matching query does not exist.
>>> a1 = Article.objects.get(pk=1)
>>> a1.was_published_recently()
True
>>> a1.bookmark_set.all()
>>> a1.bookmark_set.create(comment='good!', stars=0)
>>> a1.bookmark_set.create(comment='bad', stars=10)
>>> b3 = a1.bookmark_set.create(comment='???', stars=2)
>>> b3.comment
'???'
>>> Bookmark.objects.filter(article__published__year=current_year)
, , ]>
>>> b3.delete()
(1, {'bookmarker.Bookmark': 1})
>>> Bookmark.objects.filter(article__published__year=current_year)
, ]>
管理画面
管理ユーザ作成
> python manage.py createsuperuser
Username (leave blank to use 'xxxx'): admin
Email address: admin@example.com
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
Password:
Password (again):
Superuser created successfully.
最初passにしようとしたらtoo short too commonと怒られた。
passpassにしたら通った。これでいいのか?
アプリ起動
> python manage.py runserver
http://localhost:8000/admin
にアクセス
ログイン後
追加したモデルを管理対象にする
bookmaker/admin.py
from django.contrib import admin
# Register your models here.
from .models import Article, Bookmark
admin.site.register(Article)
admin.site.register(Bookmark)
もう一回アクセス
Articlesをクリック
This is the first article.をクリック
ちゃんとタイムゾーンで指定した通り、日本時間で表示されている
MySQLのDB内を直接のぞくと、UTCになっている
ちなみに、MySQL Workbenchを使っている
https://www.mysql.com/jp/products/workbench/
20日に変更して保存
これでチュートリアル2は終わり
おまけ: Herokumへのデプロイ
デプロイの手順の記事