Djangoのモデルの利用例
Djangoのモデルの利用例
モデルクラスとフォームクラスの利用パターンの備忘録
モデルクラスのフィールドクラスのオプション
オプション名 | 説明 | デフォルト |
---|---|---|
null | Trueの場合、DEFAULT NULL、Falseの場合、NOT NULL | False |
balnk | Trueの場合、空が許容される | False |
choises | 選択肢を設定する。ウィジェットがセレクトボックスになる | |
db_column | テーブルのカラム名になる | 変数名がカラム名 |
db_index | テーブルのカラム名にインデックスを張る | |
default | デフォルト値、フィールドを設定しない場合の値 | |
editable | Trueの場合、編集可能。Falseの場合、編集できない | True |
error_messages | エラーメッセージ文字列、フォームで利用 | |
help_text | フォームの説明用文字列、フォームで利用 | |
primary_key | Trueの場合、モデルの主キーになる。重複はダメ | |
unique | ユニーク制約を張る | |
verbose_name | フォームでの表記名 | |
validators | 倍でーしょんの設定。リストで行う |
UUIDの主キー
主キーは自動的に設定されるので、特に設定は不要。UUIDにする場合、以下のようにする
from django.db import models
import uuid
class Player(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False,
)
MySQLの場合、テーブルのカラムは以下のようにchar(32)になっている
`id` char(32) NOT NULL,
CharField
文字列のフィールドの設定例です。NULLを許容している。空を許容している。フィールドを省略すると空文字が入る
フォームのデフォルトはTextInputになる
class Player(models.Model):
name = models.CharField(
verbose_name='名前', # フォームの表示名
max_length=255, # 桁数、必須オプション
blank=True, # 空を許容する
null=True, # NULLを許容する DEFAULT NULL
default='', # デフォルトが空文字
validators=[validators.RegexValidator(
regex=u'^[ぁ-んァ-ヶー一-龠]+$',
message='全角のひらがな・カタカナ・漢字で入力してください',
)],
)
テーブルのカラムの設定は以下のようになる。DEFAULT NULLになっている
`name` varchar(255) DEFAULT NULL,
NULLを許容しない
NULLを許容しないなら、これだけでよい。
class Player(models.Model):
name = models.CharField(
verbose_name='名前', # フォームの表示名
max_length=255, # 桁数、必須オプション
)
IntegerField
整数のフィールドです
class Player(models.Model):
age = models.IntegerField(
verbose_name='年齢', # 表示名
default=0, # 初期値
validators=[
validators.MinValueValidator(0), # 最小値
validators.MaxValueValidator(150) # 最大値
],
)
フォームはNumberInputになる。デフォルトでは、type="number"を表示する
choicesを設定する
choicesを設定するとフォーム側に選択肢を設定する。ウィジェットがNumberInputからSelectになる。テーブルのカラム定義には影響しない。あくまでもフォームのウィジェットが変更されるだけ
class Player(models.Model):
age = models.IntegerField(
verbose_name='年齢',
default=0,
validators=[
validators.MinValueValidator(0),
validators.MaxValueValidator(100)
],
choices=(
(10, '10才'),
(20, '20才'),
(30, '30才'),
)
)
BooleanField
True/Falseを設定するフィールド。ON/OFFを制御するカラムになる。要するに、Trueなら「1」、Falseなら「0」を登録する
class Player(models.Model):
isActive = models.BooleanField(
verbose_name='有効フラグ',
default=True,
)
MySQLでは、テーブルのカラムはtinyintになる
`isActive` tinyint(1) NOT NULL,
フォームはデフォルトでは、チェックボックスになる
Nullを許容する
null=TrueにするとNullを許容する。default=Noneにすることで、初期値が「NULL」になる。フィールドに値を代入しない場合、初期値「NULL」で登録される
class Player(models.Model):
isActive = models.BooleanField(
verbose_name='有効フラグ',
null=True,
default=None,
)
テーブル定義はDEFAULT NULLになる
`isActive` tinyint(1) DEFAULT NULL,
フォームはデフォルトでは、SELECTになる。選択肢は「はい」「いいえ」「不明」。「不明」の場合、pythonでは、「None」になる。テーブルには「NULL」で代入される
DateTimeField
DateTimeでのフィールド。DateTimeの利用に利用可能。
from django.utils import timezone
class Player(models.Model):
startTime = models.DateTimeField(
verbose_name='開始時刻',
default=timezone.now
)
テーブルの定義は以下のようになる
`startTime` datetime(6) NOT NULL,
フォームでのウィジェットはDateTimeInputだが、実際にはただのテキストボックスになる。管理画面では、JSを含めた2個の入力パーツになる
登録日時と更新日時
登録日時、更新日時に利用可能。auto_now_add=Trueにすると登録日時になる。auto_now=Trueにすると更新日時になる。この場合、フォームには表示されない
class Player(models.Model):
created_at = models.DateTimeField(
verbose_name='新規登録日時',
auto_now_add=True
)
modified_at = models.DateTimeField(
verbose_name='更新日時',
auto_now=True
)
テーブルのカラムは以下のようになる
`created_at` datetime(6) NOT NULL,
`modified_at` datetime(6) NOT NULL,
DateField
Dateでのフィールド。Dateの利用に利用可能。
from datetime import date
class Player(models.Model):
birthday = models.DateField(
verbose_name='誕生日',
default=date.today,
)
テーブルのカラムは以下のようになる
`birthday` date NOT NULL,
フォームのデフォルトはTextInputなので、ただのtype="text"になる
モデルフォームでのウィジェットの変更
モデルフォームで、フィールドのウィジェットを変更する。type="date"に変更する
class PlayerForm(forms.ModelForm):
class Meta:
model = Player
fields = ['birthday']
widgets = {
'birthday': forms.TextInput(attrs={"type": "date"}),
}
複数の選択肢
フォーム上での選択肢の設定を行う。choicesを設定することで選択肢を表示する。ただし、これはフォームクラスと連動した場合のみ。モデルを単体で利用する場合、自由に値が代入される可能性がある
セレクトボックス
CharFiledでも、IntegerFieldでもchoicesを設定することでフォーム側では自動的にセレクトボックスになる。フォームでウィジェットの設定は不要
class Player(models.Model):
job = models.CharField(
verbose_name="職業",
max_length=255,
choices=(
('hero', '勇者'),
('fighter', '戦士'),
('magician', '魔法使い'),
('dancer', '踊り子'),
)
)
フォームクラスは設定しなくても構わないが、あえて設定するから、以下のようになる
class PlayerForm(forms.ModelForm):
class Meta:
model = Player
fields = ['job']
widgets = {
'job':forms.Select(),
}
ラジオボタン
フォームクラスで変更する。モデルクラスの設定は、セレクトボックスの設定と同じでも構わない。フォームクラスのウィジェットを変更することで対応可能
class PlayerForm(forms.ModelForm):
class Meta:
model = Player
fields = ['job']
widgets = {
'job':forms.RadioSelect(),
}
デフォルトの「-----」をなくすためには、モデル側でdefault='XXX'を設定する
class Player(models.Model):
job = models.CharField(
verbose_name="職業",
max_length=255,
choices=(
('hero', '勇者'),
('fighter', '戦士'),
('magician', '魔法使い'),
('dancer', '踊り子'),
),
default='hero',
)
横に並べるならCSSを変更する
チェックボックス
True/False、つまり、ON/OFFだけのチェックボックスなら、BooleanFieldを定義することで1個のチェックボックスを作ることが可能
class Player(models.Model):
isActive = models.BooleanField(
verbose_name='有効フラグ',
default=True,
)
BooleanFieldのデフォルトウィジェットはチェックボックスなので、ON/OFFのチェックボックスになる。フォームの設定は不要
複数選択可能なチェックボックス
チェックボックスで複数をチェック可能にする場合、多対多を構築する。これで、多対多を利用したチェックボックスの登録が可能になる
class PlayerType(models.Model):
name = models.CharField(
verbose_name='タイプ名',
max_length=255,
)
def __str__(self):
return self.name
class Player(models.Model):
type = models.ManyToManyField(
PlayerType,
verbose_name='タイプ')
この場合、フォームではウィジェットの設定をしなくても複数選択可能なSELECTになる。あえて、設定するならSelectMultipleを設定する。設定しなくても自動的に服須選択可能なセレクトボックスになる
class PlayerForm(forms.ModelForm):
class Meta:
model = Player
fields = ['type']
widgets = {
'type':forms.SelectMultiple(),
}
チェックボックスにするなら以下のように、CheckboxSelectMultipleのウィジェットを設定する
class PlayerForm(forms.ModelForm):
class Meta:
model = Player
fields = ['type']
widgets = {
'type':forms.CheckboxSelectMultiple(),
}
複数を選択するチェックボックス
多対多ではなく、1カラムにチェックボックスで複数の値を代入する場合の例です。モデルのフィールドでJSONFieldを利用します。これにより、テーブルに格納されるデータはJSON化された状態でデータを保持します
class Player(models.Model):
job = models.JSONField(
verbose_name="職業",
default='',
)
フォーム側では、複数選択可能なチェックボックスにします
class PlayerForm(forms.ModelForm):
class Meta:
model = Player
fields = ['job']
job = forms.MultipleChoiceField(
label="職業",
widget=forms.CheckboxSelectMultiple(),
choices=(
('hero', '勇者'),
('fighter', '戦士'),
('magician', '魔法使い'),
('dancer', '踊り子'),
),
)
テーブルのレコードには、リストをJSON化した状態で保存されます。ビュー処理のCreateViewでも、UpdateViewでもJSONデータを取り出して、チェックボックスに正しく反映します。CreateViewでも、UpdateViewでも、特別な手続きは不要
フォームクラスでのセレクト、ラジオ、チェックボックス
モデルと連動しないフォームパーツを作る場合の例です
セレクトボックス
普通のフォームクラスになる。継承元が、Modelformではなく、ただのFormになる。フォームのフィールドクラスをChoiceFieldにする。ウィジェットはなくてもよいが、デフォルトでSelectになる。あえて設定するなら以下のようになる
class PlayerForm (forms.Form):
music = forms.ChoiceField(
label="好きな音楽",
choices=(
('jpop','JPOP'),
('rock','ロック'),
('anime','アニソン'),
('vocaloid','ボーカロイド'),
),
initial = "",
widget=forms.Select(),
)
ラジオボタン
ウィジェットをRadioSelectにする
class PlayerForm (forms.Form):
music = forms.ChoiceField(
label="好きな音楽",
choices=(
('jpop','JPOP'),
('rock','ロック'),
('anime','アニソン'),
('vocaloid','ボーカロイド'),
),
initial = "",
widget=forms.RadioSelect(),
)
複数選択可能なチェックボックス
ウィジェットをCheckboxSelectMultipleにする
class PlayerForm (forms.Form):
music = forms.ChoiceField(
label="好きな音楽",
choices=(
('jpop','JPOP'),
('rock','ロック'),
('anime','アニソン'),
('vocaloid','ボーカロイド'),
),
initial = "",
widget=forms.CheckboxSelectMultiple(),
)
Discussion