Help us understand the problem. What is going on with this article?

[Django] モデルフィールド 設定テンプレート

More than 1 year has passed since last update.

この記事について

コピペで使えるようにしたモデルフィールドの定義例+α。

参考:公式 モデルフィールドリファレンス

共通オプションの説明

一部のみ

オプション名 説明 デフォルト
verbose_name 入力欄のタイトル なし
blank ブランク入力 False(不可)
null 別記参照 Fales(Not Null)
default デフォルト値 なし
editable フォームでの表示 True(=表示する)
max_length 最大文字長 フィールド別
help_text ツールチップの内容 なし

フィールド定義例

文字列:CharField

入力値:文字列
入力項目:テキストボックス(text)

models.py
    myChar = models.CharField(
        verbose_name='',
        blank=True,
        null=True,
        max_length=50,
        default='',
        validators=[validators.RegexValidator(
            regex=u'^[ぁ-んァ-ヶー一-龠]+$',
            message='全角のひらがな・カタカナ・漢字で入力してください',
        )]
    )

[派生フィールド]

フィールド型 用途
SlugField スラッグ
URLField URL
EmailField メールアドレス
UUIDField UUID
FilePathField ファイルパス
GenericIPAddressField IPアドレス(v4/v6/両方)
  • 専用のバリデーションが付く
  • DBによっては専用のカラム型が使われる(別項参照)

文字列:TextField

入力項目:テキストエリア

models.py
    myText = models.TextField(
        verbose_name='',
        blank=True,
        null=True,
        max_length=1000,
    )

整数:IntegerField

入力項目:テキストボックス(nunber)

models.py
    myInteger = models.IntegerField(
        verbose_name='',
        blank=True,
        null=True,
        default=0,
        validators=[validators.MinValueValidator(0),
                    validators.MaxValueValidator(100)]
    )

[派生フィールド]

最小最大値の制限が異なる

フィールド 最小値 最大値
IntegerField -2147483648 2147483647
SmallIntegerField -32768 32767
PositiveIntegerField 0 2147483647
PositiveSmallIntegerField 0 32767
BigIntegerField -9223372036854775808 9223372036854775807

浮動小数点:FloatField

入力項目:テキストボックス(nunber)

models.py
myFloat = models.FloatField(
    verbose_name='',
    blank=True,
    null=True,
    default=0,
       [validators.MinValueValidator(0.001),
        validators.MaxValueValidator(0.999)])
)

固定小数点:DecimalField

入力項目:テキストボックス(nunber)

専用オプション

  • max_digits 数字部分の最大桁数,
  • decimal_places 小数部分の桁数

(max_digits=5, decimal_places=2) なら -999.99 ~ 999.99 が有効値となる

models.py
myfield = models.DecimalField(
    verbose_name='',
    max_digits=5,
    decimal_places=2
    blank=True,
    null=True,
    default=0.00,
       [validators.MinValueValidator(0.01),
        validators.MaxValueValidator(100.00)])
)

論理値:BooleanField

入力項目:チェックボックス

models.py
    myBoolean = models.BooleanField(
        verbose_name='',
        default=False,
    )

論理値:NullBooleanField

Nullが可能なBooleanField
入力項目:セレクトボックス「不明・はい・いいえ」

models.py
    myNullBoolean = models.NullBooleanField(
        verbose_name='',
        default=Null,
    )

時間:DateTimeField

[専用オプション]

  • auto_now_add = True
    • 登録時に現在時間を設定
  • auto_now = True
    • 登録時と更新時に現在時間を設定

どちらかを設定するとeditable=Falseが暗黙的に設定され、モデルフォーム上に表示されなくなる。

models.py
    from django.utils import timezone

    myDateTime = models.DateTimeField(
        verbose_name='',
        blank=True,
        null=True,
        default=timezone.now
    )

[類似フィールド]

フィールド
TimeField 時間
DateField 日付
DurationField 期間

ファイル系

FileField、ImageField についてはこちらを参照
- ファイルアップロード機能の使い方 [基本設定編]
- ファイルアップロード機能の使い方 [クラウドストレージ編]

リレーション系

リレーション先のモデルは先に定義する。

models.py
    # 1 x N
    parent = models.ForeignKey(
        Parent, 
        on_delete=models.CASCADE)

    # 1 x 1
    parent = models.OneToOneField(
        Parent, 
        on_delete=models.CASCADE)

    # N x N
    many = models.ManyToManyField(Many)

nullオプションについて

仕様がややこしい。

  • null=False時

    • カラム定義にNOT NULL制約が付与される
    • 文字列入力欄が空の時は空文字が設定される。文字列以外のフィールドはDBエラーを出す。
  • null=True時

    • カラム定義にNOT NULL制約が付与されない
    • 入力欄が空の時はNULLが設定される。

ただしOracleでは空文字が使えないため、文字列フィールドについては「null=False」を指定してもマイグレーション時に「null=True」として扱われる。

以下のルールで運用しないと空文字とNullが混在するので注意する

  • 「blank=Ture」を定義したときは必ず「null=Ture」も設定する
    • ブランクは「null」になる。
  • もしくは「null」オプションを一切使わない。
    • ブランクは「空文字」になる。

上で統一した方がいい気がするが判断基準がみつからない…。

choiceオプションについて

choiceオプションを使って入力項目を選択項目にできる。
入力ウィジェットはデフォルトでセレクトボックスだが、モデルフォームを定義することでラジオボタンやリストボックスにに変更可能である。

    YEAR_CHOICES = (
        (10, '10代'),
        (20, '20代'),
        (30, '30代'),
        (40, '40代'),
    )

    age = models.IntegerField(
        verbose_name="年齢",
        choices=YEAR_CHOICES)

以下の定義だと、optgroupタグでグループ化されたセレクトボックスになる。

    MENU_CHOICES = (
        ('食事', (
            ('Curry', 'カレー'),
            ('Ramen', 'ラーメン'),
        )),
        ('飲み物', (
            ('Bear', 'ビール'),
            ('Juice', 'ジュース'),
        )),
    )

    menu = models.CharField(
        verbose_name="メニュー",
        max_length=10,
        choices=MENU_CHOICES)

choiceオプションはcallableであり、タプルを返す関数を指定すれば動的なリストを作ることができる

モデルフィールド x DBカラム対応表

データベース SQLite3 Postgres9.6 MySQL5.7 Oracle 12.1 SQL Server 2017
AutoField integer serial integer NUMBER int
CharField varchar varchar varchar NVARCHAR2 nvarchar
SlugField varchar varchar varchar NVARCHAR2 nvarchar
URLField varchar varchar varchar NVARCHAR2 nvarchar
EmailField varchar varchar varchar NVARCHAR2 nvarchar
UUIDField char uuid char VARCHAR2 char
FilePathField varchar varchar varchar NVARCHAR2 nvarchar
GenericIPAddressField char inet char VARCHAR2 nvarchar
TextField text text longtext NCLOB nvarchar
IntegerField integer integer integer NUMBER int
SmallIntegerField smallint smallint smallint NUMBER smallint
BigIntegerField bigint bigint bigint NUMBER NOT bigint
PositiveIntegerField integer unsigned integer integer NUMBER int
PositiveSmallIntegerField smallint unsigned smallint smallint NUMBER smallint
FloatField real double precision double precision DOUBLE PRECISION double precision
DecimalField decimal numeric numeric NUMBER numeric
BooleanField bool boolean bool NUMBER bit
NullBooleanField bool boolean bool NUMBER bit
TimeField time time time TIMESTAMP time
DateField date date date DATE date
DateTimeField datetime timestamp with time zone datetime TIMESTAMP datetime2
DurationField bigint interval bigint INTERVAL bigint
BinaryField BLOB bytea longblob BLOB varbinary
FileField varchar varchar varchar NVARCHAR2 nvarchar
ImageField varchar varchar varchar NVARCHAR2 nvarchar
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした