教材の内容に関係のない質問や教材とは異なる環境・バージョンで進めている場合のエラーなど、教材に関係しない質問は推奨していないため回答できない場合がございます。
その場合、teratailなどの外部サイトを利用して質問することをおすすめします。教材の誤字脱字や追記・改善の要望は「文章の間違いや改善点の指摘」からお願いします。
初期マイグレーションのパートでも少しお話ししましたが、モデルとはそのシステム内で扱いたいひとまとまりのデータとその振る舞いを定義したものになります。Djangoの開発では基本的にSQL文は使用せず、このモデルに対する操作でデータの管理を行います。一つのモデルに対し、一つのテーブルが作成され、モデルを定義する際はdjango.db.models.Modelクラスを継承して独自のモデルを定義します。
このパートでは商品に対応するモデルを作成します。
モデルはアプリフォルダに生成されているmodels.pyに記述します。
早速商品モデルを作成しましょう。
models.py
を以下のコードのように修正してください。
Copied!techpit/
└ amazon/
├ static/
├ __init__.py
├ apps.py
├ models.py ← このファイルを修正します。
├ views.py
├ admin.py
├ migrations/
└ test.py
amazon/models.py1234567891011121314151617181920212223242526 Copied!## 中略 ##
# [3-1] 商品クラス追加 ここから
class Product(models.Model):
class Meta:
verbose_name = '商品'
verbose_name_plural = "商品"
thumbnail = models.ImageField(
verbose_name = 'サムネイル',
upload_to = "thumbnails/"
)
name = models.CharField(
verbose_name = '名前',
max_length=150,
null = False,
blank=False
)
price = models.IntegerField(
verbose_name = '価格'
)
description = models.TextField(
verbose_name = '説明'
)
# [3-1] 商品クラス追加 ここまで
各フィールド(データカラムに相当)はdjango.db.modelsで定義されている各フィールドから選択し、継承して定義します。
フィールドの種類は様々ありますが、上記で記載されている各フィールドを説明いたします。
各引数について
以上で商品モデルの定義が完了しました。
新しくモデルを定義したらマイグレーションをしましょう。
仮想環境に入っている状態で、manage.pyファイルと同じフォルダへ移動し、以下のコマンドを打ちます。
shell12345 Copied!(myenv)$ python manage.py makemigrations amazon
Migrations for 'amazon':
amazon/migrations/0001_initial.py
- Create model Product
これで新しいマイグレーションファイルが作成されました。
次に実際にマイグレーションしていきます。
shell12345 Copied!(myenv)$ python manage.py migrate amazon
Operations to perform:
Apply all migrations: amazon
Running migrations:
Applying amazon.0001_initial... OK
これで商品モデルに対応するテーブルがデータベースに作成されました。
実際にテーブルが追加されていることを確認しましょう。
shell12345678910 Copied!(myenv)$ sqlite3 db.sqlite3
SQLite version 3.24.0 2018-06-04 14:10:15
Enter ".help" for usage hints.
sqlite> .tables
amazon_product auth_user_user_permissions
auth_group django_admin_log
auth_group_permissions django_content_type
auth_permission django_migrations
auth_user django_session
auth_user_groups
テーブルは[アプリ名]_[モデル名]で作成されます。
amazon_productというテーブルが作成されていることがわかります。
モデルを作成し、マイグレーションによってテーブルを作成したので、初期データを投入しましょう。
Djangoでは、fixtureというjsonデータから初期データを一括で投入できるコマンドが用意されています。
今回はこのコマンドを利用して商品データを投入してみましょう。
まずはアプリフォルダの中にfixtures
フォルダを作成し、その中にinitial_data.json
というファイルを作成しましょう。
Copied!amazon/
├ static/
├ fixtures/ ← 追加
┃ └ initial_data.json ← 追加
├ __init__.py
├ apps.py
├ models.py
├ views.py
├ admin.py
├ migrations/
└ test.py
作成したらinitial_data.json
に以下のコードを追加してください。
amazon/fixtures/initial_data.json1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 Copied![
{
"model": "amazon.Product",
"pk": 1,
"fields": {
"thumbnail": "1.jpg",
"name": "アイロン",
"price": 10000.0,
"description": "非常に使いやすいアイロンです。"
}
},
{
"model": "amazon.Product",
"pk": 2,
"fields": {
"thumbnail": "2.jpg",
"name": "ブレンダー",
"price": 200.0,
"description": "様々なものをブレンドできます。"
}
},
{
"model": "amazon.Product",
"pk": 3,
"fields": {
"thumbnail": "3.jpg",
"name": "バッグ",
"price": 30000.0,
"description": "おしゃれなバッグです。"
}
},
{
"model": "amazon.Product",
"pk": 4,
"fields": {
"thumbnail": "4.jpg",
"name": "スマートフォン",
"price": 20000.0,
"description": "使いやすいスマートフォンです。"
}
},
{
"model": "amazon.Product",
"pk": 5,
"fields": {
"thumbnail": "5.jpg",
"name": "ソファ",
"price": 2600000.0,
"description": "上質な素材を使ったソファです。"
}
},
{
"model": "amazon.Product",
"pk": 6,
"fields": {
"thumbnail": "6.jpg",
"name": "チェア",
"price": 260000.0,
"description": "上質な素材を使ったチェアです。"
}
},
{
"model": "amazon.Product",
"pk": 7,
"fields": {
"thumbnail": "7.jpg",
"name": "腕時計",
"price": 76000.0,
"description": "おしゃれな腕時計です。"
}
},
{
"model": "amazon.Product",
"pk": 8,
"fields": {
"thumbnail": "8.jpg",
"name": "ディスプレイ",
"price": 6000.0,
"description": "リーズナブルなディスプレイです。"
}
}
]
1オブジェクトが1jsonオブジェクトに対応するので、上記ファイルでは計8レコードを定義しております。model項目にモデルクラスを指定し、pkには主キー、fieldsには各フィールドを定義します。nameやprice等はそのままなので説明は不要かと思いますが、ImageFieldのthumbnailについては少し特殊です。ImageFieldやFileFieldの項目については、登録する画像ファイルのパスを指定するのですが、その際のルートフォルダとなるのが、MEDIA_ROOT(詳しくは1-4参照)です。
1-4でtechpit/mediaフォルダを作成していますので、そのフォルダの直下に画像ファイルを置きましょう。
ダウンロードした静的ファイル(staticフォルダ)のstatic/images/items/下の商品画像を全てmediaフォルダにコピーします。
Copied!techpit/
├ amazon/
├ static/
├ media/
├ 1.jpg ← 配置
└ ・・・
開発中の確認時等、Djangoの開発用サーバ(manage.py runserverコマンド)を利用すると、静的ファイルやメディアファイルの扱い(クライアントからの要求に対してファイルを返すようなWebサーバの仕事)もdjangoの開発サーバに実施してもらいます。そのため、このmediaファイルに対してもルーティングを追加してやる必要があります。(今回はstaticフォルダの中身は外部に公開しないためmediaフォルダのルーティングのみ追加します)
techpit/urls.pyを以下のように修正しましょう。
Copied!techpit
└── urls.py
techpit/urls.py1234567 Copied!〜略〜
from django.conf.urls.static import static # 追加
urlpatterns = [
path('techpit/admin/', admin.site.urls),
path('techpit/amazon/', include('amazon.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # 追加
これで、MEDIA_URLへきたリクエストをdjangoが処理できるようになります。
データの投入は以下のコマンドで実行します。
shell12 Copied!(myenv)$ python manage.py loaddata initial_data.json
Installed 8 object(s) from 1 fixture(s)
上記のようになっていれば成功です。
実際にDBをのぞいてみましょう。
shell12345678910111213 Copied!(myenv)$ sqlite3 db.sqlite3
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite> select * from amazon_product;
1|1.jpg|アイロン|10000|非常に使いやすいアイロンです。
2|2.jpg|ブレンダー|200|様々なものをブレンドできます。
3|3.jpg|バッグ|30000|おしゃれなバッグです。
4|4.jpg|スマートフォン|20000|使いやすいスマートフォンです。
5|5.jpg|ソファ|2600000|上質な素材を使ったソファです。
6|6.jpg|チェア|260000|上質な素材を使ったチェアです。
7|7.jpg|腕時計|76000|おしゃれな腕時計です。
8|8.jpg|ディスプレイ|6000|リーズナブルなディスプレイです。
sqlite>
8件データを確認できました。
以上で今回のパートは終了です。
お疲れ様でした。