djangoでnull = True、blank = Trueを区別する

2011-12-23 python django django-models

djangoにデータベースフィールドを追加するとき、通常は次のように記述します。

models.CharField(max_length=100, null=True, blank=True)

同じことが、 ForeignKeyDecimalFieldなどでも行われます。

  1. null=Trueのみ
  2. blank=Trueのみ
  3. null=Trueblank=True

さまざまな( CharFieldForeignKeyManyToManyFieldDateTimeField )フィールドに関して。 1/2/3を使用する利点と欠点は何ですか?

Answers

null=Trueは、DBの列に( NOT NULLNULL設定しNULLDateTimeFieldForeignKeyなどのDjangoフィールドタイプの空の値は、DBにNULLとして格納されNULL

blankは、フィールドがフォームで必須になるかどうかを決定します。これには、管理者とカスタムフォームが含まれます。 blank=True場合、フィールドは必須ではありませんが、 Falseの場合、フィールドを空白にすることはできません。

通常、フォーム内のフィールドを空白にできるようにする場合は、データベースでそのフィールドにNULL値を許可する必要があるため、この2つの組み合わせは頻繁に発生します。例外はCharFieldTextFieldです。これらはDjangoでは決して NULLとして保存されません 。空白の値は、空の文字列( '' )としてDBに格納されます。

いくつかの例:

models.DateTimeField(blank=True) # raises IntegrityError if blank

models.DateTimeField(null=True) # NULL allowed, but must be filled out in a form

明らかに、これらの2つのオプションは論理的に使用しても意味がありません(フォームでフィールドを常に必須にする場合はnull=True, blank=False使用例がありますが、次のようなものを介してオブジェクトを処理する場合はオプションです。シェル。)

models.CharField(blank=True) # No problem, blank is stored as ''

models.CharField(null=True) # NULL allowed, but will never be set as NULL

CHARおよびTEXT型はDjangoによってNULLとして保存されることはないため、 null=Trueは不要です。ただし、これらのフィールドの1つを手動でNoneに設定して、強制的にNULL設定できNULL 。それが必要になる可能性のあるシナリオがある場合でも、 null=True含める必要がありnull=True

これは、ORMはマッピングする方法であるblanknull Djangoの1.8用のフィールドを

class Test(models.Model):
    charNull        = models.CharField(max_length=10, null=True)
    charBlank       = models.CharField(max_length=10, blank=True)
    charNullBlank   = models.CharField(max_length=10, null=True, blank=True)

    intNull         = models.IntegerField(null=True)
    intBlank        = models.IntegerField(blank=True)
    intNullBlank    = models.IntegerField(null=True, blank=True)

    dateNull        = models.DateTimeField(null=True)
    dateBlank       = models.DateTimeField(blank=True)
    dateNullBlank   = models.DateTimeField(null=True, blank=True)        

PostgreSQL 9.4用に作成されたデータベースフィールドは次のとおりです。

CREATE TABLE Test (
  id              serial                    NOT NULL,

  "charNull"      character varying(10),
  "charBlank"     character varying(10)     NOT NULL,
  "charNullBlank" character varying(10),

  "intNull"       integer,
  "intBlank"      integer                   NOT NULL,
  "intNullBlank"  integer,

  "dateNull"      timestamp with time zone,
  "dateBlank"     timestamp with time zone  NOT NULL,
  "dateNullBlank" timestamp with time zone,
  CONSTRAINT Test_pkey PRIMARY KEY (id)
)

MySQL 5.6用に作成されたデータベースフィールドは次のとおりです。

CREATE TABLE Test (
     `id`            INT(11)     NOT  NULL    AUTO_INCREMENT,

     `charNull`      VARCHAR(10) NULL DEFAULT NULL,
     `charBlank`     VARCHAR(10) NOT  NULL,
     `charNullBlank` VARCHAR(10) NULL DEFAULT NULL,

     `intNull`       INT(11)     NULL DEFAULT NULL,
     `intBlank`      INT(11)     NOT  NULL,
     `intNullBlank`  INT(11)     NULL DEFAULT NULL,

     `dateNull`      DATETIME    NULL DEFAULT NULL,
     `dateBlank`     DATETIME    NOT  NULL,
     `dateNullBlank` DATETIME    NULL DEFAULT NULL
)

Djangoモデルフィールドリファレンスで述べたように: リンク

フィールドオプション

次の引数は、すべてのフィールドタイプで使用できます。すべてオプションです。


null

Field.null

True場合、Djangoは空の値をNULLとしてデータベースに格納します。デフォルトはFalseです。

CharFieldなどの文字列ベースのフィールドでnullを使用しないでください。 空の文字列値は常に空として格納されるため、 TextField NULLではなく文字列。文字列ベースのフィールドにnull=True場合、 「データなし」の2つの可能な値があることを意味しNULLNULLと空 ストリング。ほとんどの場合、2つの可能な値を持つことは冗長です "データなし"; Djangoの慣習では、空の文字列を使用します。 NULL

文字列ベースのフィールドと非文字列ベースのフィールドの両方について、以下も必要です。 空の値をフォームで許可する場合は、 blank=Trueを設定しblank=True nullパラメータはデータベースストレージにのみ影響します( blank参照)。

注意

Oracleデータベースバックエンドを使用する場合、この属性に関係なく、値NULLが格納されて空の文字列を示します。


blank

Field.blank

True場合、フィールドは空白にできます。デフォルトはFalseです。

これはnullとは異なることに注意してください。 nullは純粋に blankは検証関連ですが、データベース関連です。フィールドの場合 blank=True 、フォームの検証で空の値を入力できます。 フィールドにblank=Falseがある場合、フィールドは必須です。

単にnull=TrueはデータベースがNULL値を受け入れることを定義します、他方、 blank=Trueはフォーム検証でこのフィールドが空白値を受け入れるかどうかを定義します( blank=Trueの場合、そのフィールドに値のないフォームを受け入れ、 blank=False [デフォルト値]フォーム検証時に表示されますこのフィールドは必須エラーです。

null=True/Falseデータベースに関連するnull=True/False

blank=True/Falseフォーム検証に関連するblank=True/False

次に、 blank= Trueおよびnull=Trueフィールドの例を示します。

description = models.TextField(blank = True、null = True)

この場合: blank = True :説明フィールドを空白のままにしてよいことをフォームに伝えます

そして

null = True :データベースにnull値を記録しても問題はなく、エラーが発生しないことをデータベースに通知します。

Django adminに何かを保存すると、Djangoレベルとデータベースレベルの2つのステップで検証が行われます。数値フィールドにテキストを保存することはできません。

データベースのデータ型はNULLですが、何もありません。 Djangoはデータベースに列を作成するときに、空にすることはできないことを指定します。また、NULLを保存しようとすると、データベースエラーが発生します。

また、Django-Adminレベルでは、デフォルトですべてのフィールドが必須です。空白のフィールドを保存することはできません。Djangoはエラーをスローします。

したがって、空白のフィールドを保存する場合は、Djangoおよびデータベースレベルで許可する必要があります。 blank = True-管理パネルで空のフィールドを許可する null = True-NULLをデータベース列に保存できます。

Djangoモデルフィールド定義のオプションが(少なくとも)2つの目的を果たしていることを理解することが重要です。データベーステーブルの定義と、デフォルトのフォーマットの定義とモデルフォームの検証です。 (値は常にカスタムフォームを提供することでオーバーライドできるため、「デフォルト」と言います。)データベースに影響するオプション、フォームに影響するオプション、両方に影響するオプションがあります。

nullblankに関しては、前者はデータベーステーブルの定義に影響を与え、後者はモデルの検証に影響を与えるという他の答えがすでに明らかになっています。考えられる4つの構成すべてのユースケースを見ると、区別がさらに明確になると思います。

  • null=Falseblank=False :これはデフォルトの構成であり、すべての状況で値が必要であることを意味します。

  • null=Trueblank=True :これは、すべての状況でフィールドがオプションであることを意味します。 (ただし、下記のように、これは文字列ベースのフィールドをオプションにするための推奨される方法ではありません 。)

  • null=Falseblank=True :これは、フォームには値は必要ありませんが、データベースには必要であることを意味します。これにはいくつかの使用例があります。

    • 最も一般的な用途は、オプションの文字列ベースのフィールドです。 ドキュメント記載されているように、Djangoイディオムは空の文字列を使用して欠損値を示すことです。 NULLも許可された場合、欠損値を示すために2つの異なる方法を使用することになります。

    • 別の一般的な状況は、 save()たとえばsave()メソッドでsave()別のフィールドの値に基づいて1つのフィールドを自動的に計算したい場合です。ユーザーに値をフォームで提供してほしくない(したがってblank=True )が、データベースで値が常に提供されるように強制したい( null=False )。

    • もう1つの用途は、 ManyToManyFieldがオプションであることを示す場合です。このフィールドはデータベース列ではなく別のテーブルとして実装されるため、 nullは意味がありません 。ただし、 blankの値はフォームに影響しますが、関係がない場合に検証が成功するかどうかを制御します。

  • null=Trueblank=False :これは、フォームには値が必要ですが、データベースには必要ないことを意味します。これは最も使用頻度の低い構成ですが、いくつかの使用例があります。

    • ビジネスロジックで実際に要求されていない場合でも、常に値を含めるようユーザーに要求することは完全に合理的です。結局のところ、フォームはデータを追加および編集する唯一の方法です。人間のエディタに要求するのと同じ厳格な検証を必要としないデータを生成するコードがある場合があります。

    • 私が見たもう1つの使用例は、 カスケード削除を許可したくないForeignKeyがある場合です。つまり、通常の使用では、リレーションは常に存在する必要があります( blank=False )が、それが指すものが削除された場合、このオブジェクトも削除されたくないでしょう。その場合は、 null=Trueおよびon_delete=models.SET_NULLを使用して、単純な種類のソフト削除を実装できます

null = True

フィールドに入力するためのデータベースの制約がないことを意味します。そのため、このオプションを持つ、入力した値にnull値を持つオブジェクトを作成できます。

blank = True

djangoフォームには検証の制約がないことを意味します。そのため、このモデルのmodelFormmodelFormする場合、このオプションを入力せずにフィールドを残すことができます。

これがnull=Trueblank=Trueの主な違いです:

nullblankの両方のデフォルト値はFalseです。これらの値はどちらもフィールドレベルで機能します。つまり、フィールドをnullblankかです。

null=Trueは、フィールドの値をNULL設定しNULLつまり、データはありません。基本的にはデータベースの列の値です。

date = models.DateTimeField(null=True)

blank=Trueは、フィールドがフォームで必須になるかどうかを決定します。これには、管理者と独自のカスタムフォームが含まれます。

title = models.CharField(blank=True) // title can be kept blank. データベース("")に格納されます。 null=True blank=Trueこれは、フィールドがすべての状況でオプションであることを意味します。

epic = models.ForeignKey(null=True, blank=True)
// The exception is CharFields() and TextFields(), which in Django are never saved as NULL. Blank values a

CharFieldまたはTextFieldあってもnull=Trueが必要となる点が1つありnull=Trueそれは、データベースに列にuniqueフラグが設定されている場合です。

つまり、Djangoに一意のChar / TextFieldがある場合、これを使用する必要があります。

models.CharField(blank=True, null=True, unique=True)

一意でないCharFieldまたはTextFieldの場合は、 null=Trueスキップすることをお勧めします。そうしないと、一部のフィールドがNULLとして設定され、他のフィールドは ""として設定されます。また、フィールド値のNULLを毎回チェックする必要があります。

あなたはあなたの答えを持っているかもしれませんが、今日まで、フィールドにnull = Trueまたはblank = True、あるいはその両方を入れるかどうかを判断するのは困難です。私は個人的に、開発者に非常に多くのオプションを提供するのはかなり役に立たず混乱していると思います。ヌルまたはブランクを必要に応じて処理します。

はDjangoの2つのスクープからのこのテーブルに従います: ここに画像の説明を入力してください

各フィールドタイプにnullまたは空白をいつ使用するかを示す表

nullおよび空白のデフォルト値はFalseです。

Null:データベースに関連しています。特定のデータベース列がnull値を受け入れるかどうかを定義します。

空白:検証に関連しています。 form.is_valid()を呼び出すとき、フォームの検証中に使用されます。

そうは言っても、null = Trueとblank = Falseのフィールドがあっても問題ありません。データベースレベルではフィールドはNULLでもかまいませんが、アプリケーションレベルでは必須フィールドです。

さて、ほとんどの開発者が誤解しているのは、CharFieldやTextFieldなどの文字列ベースのフィールドにnull = Trueを定義することです。それをしないでください。そうしないと、「データなし 」に2つの値、つまり、 なしと空の文字列が含まれることになります。 「データなし」の2つの可能な値を持つことは冗長です。 Djangoの規約では、NULLではなく空の文字列を使用します。

nullはデータベース用、 空白はフィールドの検証用で、textfieldなどのユーザーインターフェースに表示して人の姓を取得します。 lastname = models.charfield(blank = true)の場合、これはオプションのフィールドであるため、姓の入力をユーザーに要求しませんでした。 lastname = models.charfield(null = true)の場合、このフィールドがユーザーから値を取得しない場合、データベースに空の文字列 ""として格納されます。

null-デフォルトはFalse Trueの場合、Djangoは空をnullとしてデータベースに格納します。

空白-デフォルトはFalse trueの場合、そのフィールドは空白にできます

もっと、後へ https://docs.djangoproject.com/en/3.0/topics/db/models/

以下の表は、主な違いを示しています。

+--------------------------------------------------------------------+
| Purpose                  | null=True        | blank = True         |
|--------------------------|------------------|----------------------|
| Field can be empty in DB | Do this          | Unaffected           |
|--------------------------|------------------|----------------------|
| ModelForm(required field)| Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| Form Validation          | Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| on_delete=SET_NULL       | Need this        | Unaffected           |
+--------------------------------------------------------------------+

非常に簡単な言葉で

空白はnullとは異なります。

null純粋にデータベース関連ですが、 空白は検証関連です(フォームで必須)

null=True場合、Djangoはstore empty values as NULL in the database 。フィールドにblank=Trueがある場合、フォームの検証allow entry of an empty value 。フィールドにblank = Falseがある場合、そのフィールドは必須です。

モデルにおけるnull = Trueおよびblank = Trueの意味は、これらのフィールドがフォームクラスでどのように定義されたかにも依存します。

次のクラスを定義したとします。

class Client (models.Model):
    name = models.CharField (max_length=100, blank=True)
    address = models.CharField (max_length=100, blank=False)

フォームクラスが次のように定義されている場合:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']
        widgets = {
            'name': forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
            'address': forms.TextInput (attrs = {'class': 'form-control form-control-sm'})
        }

次に、「name」フィールドは必須ではなくなり(モデルのblank = Trueにより)、「address」フィールドは必須になります(モデルのblank = Falseにより)。

ただし、ClientFormクラスが次のように定義されている場合:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']

    name = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )
    address = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )

次に、 「宣言的に定義されたフィールドはそのままにされるため」https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ )の両方のフィールド(「name」と「address」)は必須です。つまり、フォームフィールドの 'required'属性のデフォルトはTrueであり、モデルでフィールドがblank = Trueに設定されている場合でも、フィールド 'name'および 'address'に入力する必要があります。

Related