differenziere null = True, blank = True in Django


902

Wenn wir ein Datenbankfeld in Django hinzufügen, schreiben wir im Allgemeinen:

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

Das gleiche wird gemacht mit ForeignKey,DecimalField usw. Was der grundlegende Unterschied ist , in mit

  1. null=True nur
  2. blank=True nur
  3. null=True, blank=True

in Bezug auf verschiedene ( CharField, ForeignKey, ManyToManyField, DateTimeField) Felder. Was sind die Vor- und Nachteile von 1/2/3?




Ja, ich habe auch diesen Anwendungsfall ForeignKeymit blank=True, aber ohne null=True. Wenn das Modell gespeichert ist, möchte ich es automatisch "veröffentlichen", indem ich einen veröffentlichten Eintrag daraus erstelle. Ich kann also nicht nullin der Datenbank speichern, da jedes Modell "veröffentlicht" werden muss, aber ich möchte das Feld in admin leer lassen können.
osa

Ich denke, Sie könnten daran interessiert sein, [leere, nullfähige CharFields als null und nicht als leere Zeichenfolge zu speichern ] ( code.djangoproject.com/ticket/4136 ). Es gibt viele Diskussionen darüber und ein sehr praktisches Problem, auf das Sie möglicherweise stoßen (z. B. möchten Sie für jeden Benutzer eine OpenID-URL hinzufügen, die null sein kann und eindeutig sein sollte).
Ramwin

Antworten:


1082

null=Truesetzt NULL(versus NOT NULL) auf die Spalte in Ihrer DB. Leere Werte für Django-Feldtypen wie DateTimeFieldoder ForeignKeywerden wie NULLin der Datenbank gespeichert .

blanklegt fest, ob das Feld in Formularen benötigt wird. Dies umfasst den Administrator und Ihre benutzerdefinierten Formulare. Wenn blank=Truedann, wird das Feld nicht benötigt, während wenn es ist, kann Falsedas Feld nicht leer sein.

Die Kombination der beiden ist so häufig, dass Sie normalerweise auch Ihre Datenbank benötigen, um NULLWerte für dieses Feld zuzulassen , wenn Sie zulassen möchten, dass ein Feld in Ihrem Formular leer ist . Die Ausnahme sind CharFields und TextFields, die in Django niemals als gespeichert werden NULL. Leere Werte werden in der Datenbank als leere Zeichenfolge ( '') gespeichert .

Einige Beispiele:

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

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

Offensichtlich sind diese beiden Optionen nicht logisch sinnvoll zu verwenden (obwohl es einen Anwendungsfall geben kann, null=True, blank=Falsewenn ein Feld immer in Formularen benötigt werden soll, optional, wenn ein Objekt über etwas wie die Shell bearbeitet wird.)

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

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

CHARund TEXTTypen werden nie wie NULLvon Django gespeichert , null=Trueist also unnötig. Sie können jedoch eines dieser Felder manuell festlegen None, um das Festlegen als zu erzwingen NULL. Wenn Sie ein Szenario haben, in dem dies möglicherweise erforderlich ist, sollten Sie es trotzdem einbeziehen null=True.


8
IntegrityErrorwird ausgelöst, wenn Django versucht, den Datensatz in der Datenbank zu speichern. Das Feld muss nicht vom Benutzer ausgefüllt werden, und das ist das Problem, da es auf Datenbankebene nicht null ist.
Chris Pratt

5
Nein, Chris versucht darauf hinzuweisen, warum das Vorhandensein von blank = True ohne null = True Probleme in einem DateTimeField verursachen würde.
Vinod Kurup

4
HINWEIS für Oracle-Benutzer: Es ist nicht wahr, dass " CHARund TEXTNIEMALS wie NULLvon Django gespeichert werden". Es gilt für die meisten Backends, aber Oracle erzwingt eine leere Zeichenfolge auf NULL, so dass das Django Oracle-Backend eine Ausnahme von der obigen Anweisung Django Docs
stv

10
@ChrisPratt Kleinere Korrektur an Ihrem Beitrag: CharFields können als NULL in der Datenbank gespeichert werden (Übersetzung Nonein Python), wenn Sie null = True setzen. In den Dokumenten wird sogar gesagt, dass das Setzen von null = True vermieden werden soll, da zwei verschiedene Arten von "leeren" Werten zulässig sind. Ich habe dieses Verhalten gerade mit Django 1.8 / MySQL 5.6
Edward D'Souza

3
wird niemand die Kombination von erwähnen: blank=True, null=False, default="something"?
Brian H.

124

So werden die ORM-Karten blankund null-Felder für Django 1.8 erstellt

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)        

Die für PostgreSQL 9.4 erstellten Datenbankfelder sind:

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)
)

Die für MySQL 5.6 erstellten Datenbankfelder sind:

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
)

41
Mit anderen Worten, blankhat keine Auswirkung auf die Datenbank und nullsteuert, ob die Datenbankspalte NULLWerte zulässt . Diese Antwort ist ein sehr langer Weg, dies zu sagen, und liefert keine nützlichen Informationen darüber blank.
Carl Meyer

19
@CarlMeyer: Ich wollte sehen, wie es der Datenbank zugeordnet und freigegeben wird, da es anderen Zeit spart, dasselbe zu tun. Theorie und Beispiel machen einen Unterschied, wenn es darum geht, sich zu assimilieren und sich an das Gedächtnis zu binden. Tatsächlich habe ich mich sehr bemüht, das Mapping für eine Datenbank hinzuzufügen, die ich nicht verwendet habe. Danke für die Ablehnung. Die Anzahl der Personen, die dies nützlich fanden, stimmt offensichtlich nicht mit Ihnen überein.
Benutzer

5
Es könnte eine nützliche Antwort sein, wenn Sie aus den präsentierten Daten einige zusammenfassende Schlussfolgerungen ziehen, aber ich denke nicht, dass die Präsentation eines Rohdaten-Dumps eine nützliche Antwort ist. In diesem Fall handelt es sich tatsächlich um eine irreführende Antwort, da dies (ohne weiteren Kommentar) impliziert, dass die Wirkung von beiden blankund nullin den Datenbankspalten widergespiegelt werden sollte, obwohl tatsächlich blanknur die Python-Behandlung und nicht die Datenbankspalten betroffen sind. Andere können frei stimmen, wenn sie es nützlich fanden; Es ist auch möglich, dass Menschen, die durch eine irreführende Antwort irregeführt werden , dies für nützlich halten.
Carl Meyer

4
Die akzeptierte Antwort, die fast 3 Jahre alt ist, erklärt alles im Detail. Es macht keinen Sinn, die gleichen Informationen hier zu wiederholen.
Benutzer

47

Wie in Django Model Field Referenz gesagt: Link

Feldoptionen

Die folgenden Argumente stehen allen Feldtypen zur Verfügung. Alle sind optional.


null

Field.null

In diesem TrueFall speichert Django leere Werte wie NULLin der Datenbank. Standard ist False.

Vermeiden Sie die Verwendung von nullauf Zeichenfolgen basierenden Feldern wie CharFieldund, TextFieldda leere Zeichenfolgenwerte immer als leere Zeichenfolgen und nicht als gespeichert werden NULL. Wenn ein auf Zeichenfolgen basierendes Feld null=Truezwei mögliche Werte für "keine Daten" hat: NULLund die leere Zeichenfolge. In den meisten Fällen ist es überflüssig, zwei mögliche Werte für "keine Daten" zu haben. Die Django-Konvention sieht vor, die leere Zeichenfolge zu verwenden, nicht NULL.

Sowohl für stringbasierte als auch für nicht stringbasierte Felder müssen Sie festlegen, blank=Trueob leere Werte in Formularen zugelassen werden sollen, da der nullParameter nur die Datenbankspeicherung beeinflusst (siehe blank).

Hinweis

Bei Verwendung des Oracle-Datenbank-Backends wird der Wert NULL gespeichert, um die leere Zeichenfolge unabhängig von diesem Attribut zu kennzeichnen


blank

Field.blank

Wenn True, darf das Feld leer sein. Standard ist False.

Beachten Sie, dass dies anders ist als null. nullist rein datenbankbezogen, während blankvalidierungsbezogen ist. Wenn ein Feld vorhanden ist blank=True, ermöglicht die Formularüberprüfung die Eingabe eines leeren Werts. Wenn ein Feld vorhanden ist blank=False, wird das Feld benötigt.


46

Es ist wichtig zu verstehen, dass die Optionen in einer Django-Modellfelddefinition (mindestens) zwei Zwecken dienen: Definieren der Datenbanktabellen und Definieren des Standardformats und der Validierung von Modellformularen. (Ich sage "Standard", da die Werte immer durch Bereitstellen eines benutzerdefinierten Formulars überschrieben werden können.) Einige Optionen wirken sich auf die Datenbank aus, einige auf Formulare und einige auf beide.

In Bezug auf nullund blankhaben andere Antworten bereits deutlich gemacht, dass erstere die Definition der Datenbanktabelle und letztere die Modellvalidierung beeinflussen. Ich denke, die Unterscheidung kann noch deutlicher gemacht werden, wenn Anwendungsfälle für alle vier möglichen Konfigurationen betrachtet werden:

  • null=False, blank=False: Dies ist die Standardkonfiguration und bedeutet, dass der Wert unter allen Umständen erforderlich ist.

  • null=True, blank=True: Dies bedeutet, dass das Feld unter allen Umständen optional ist. (Wie unten erwähnt, ist dies jedoch nicht die empfohlene Methode, um stringbasierte Felder optional zu machen.)

  • null=False, blank=True: Dies bedeutet, dass das Formular keinen Wert benötigt, die Datenbank jedoch. Hierfür gibt es eine Reihe von Anwendungsfällen:

    • Die häufigste Verwendung sind optionale stringbasierte Felder. Wie in der Dokumentation angegeben , verwendet das Django-Idiom die leere Zeichenfolge, um einen fehlenden Wert anzuzeigen. Wenn dies NULLauch erlaubt wäre, hätten Sie zwei verschiedene Möglichkeiten, einen fehlenden Wert anzuzeigen.

    • Eine andere häufige Situation ist, dass Sie ein Feld automatisch basierend auf dem Wert eines anderen berechnen möchten ( save()z. B. in Ihrer Methode). Sie möchten nicht, dass der Benutzer den Wert in einem Formular bereitstellt (daher blank=True), aber Sie möchten, dass die Datenbank erzwingt, dass immer ein Wert angegeben wird ( null=False).

    • Eine andere Verwendung ist, wenn Sie angeben möchten, dass a ManyToManyFieldoptional ist. Da dieses Feld als separate Tabelle und nicht als Datenbankspalte implementiert nullist , ist es bedeutungslos . Der Wert von blankwirkt sich jedoch weiterhin auf Formulare aus und steuert, ob die Validierung erfolgreich ist, wenn keine Beziehungen bestehen.

  • null=True, blank=False: Dies bedeutet, dass für das Formular ein Wert erforderlich ist, für die Datenbank jedoch nicht. Dies ist möglicherweise die am seltensten verwendete Konfiguration, es gibt jedoch einige Anwendungsfälle dafür:

    • Es ist durchaus sinnvoll, von Ihren Benutzern zu verlangen, dass sie immer einen Wert angeben, auch wenn dies von Ihrer Geschäftslogik nicht tatsächlich verlangt wird. Formulare sind schließlich nur eine Möglichkeit, Daten hinzuzufügen und zu bearbeiten. Möglicherweise verfügen Sie über Code, der Daten generiert, für die nicht dieselbe strenge Validierung erforderlich ist, die Sie von einem menschlichen Editor benötigen.

    • Ein anderer Anwendungsfall, den ich gesehen habe, ist, wenn Sie einen haben, ForeignKeyfür den Sie das Löschen von Kaskaden nicht zulassen möchten . Das heißt, im normalen Gebrauch sollte die Beziehung immer vorhanden sein ( blank=False), aber wenn das Objekt, auf das es zeigt, zufällig gelöscht wird, möchten Sie nicht, dass dieses Objekt auch gelöscht wird. In diesem Fall können Sie eine einfache Art des weichen Löschens verwenden null=Trueund on_delete=models.SET_NULLimplementieren .


1
Dies ist eine perfekte Antwort, alle möglichen Kombinationen werden sehr kurz erklärt!
RusI

1
Sollte die akzeptierte Antwort sein.
Tom Mac

28

Möglicherweise haben Sie Ihre Antwort, aber bis heute ist es schwierig zu beurteilen, ob null = True oder blank = True oder beides in ein Feld eingefügt werden soll. Ich persönlich finde es ziemlich nutzlos und verwirrend, Entwicklern so viele Optionen anzubieten. Lassen Sie die Nullen oder Leerzeichen behandeln, wie sie wollen.

Ich folge dieser Tabelle aus Two Scoops of Django :Geben Sie hier die Bildbeschreibung ein

Tabelle, die zeigt, wann für jeden Feldtyp null oder leer verwendet werden muss


26

Einfach null=Truedefiniert Datenbank sollte NULLWerte akzeptieren , andererseits blank=Truedefiniert bei der Formularvalidierung, dass dieses Feld leere Werte akzeptieren soll oder nicht (Wenn blank=Truees Formular ohne Wert in diesem Feld und blank=False[Standardwert] bei der Formularvalidierung akzeptiert, wird angezeigt, dass dieses Feld ein Fehler ist.

null=True/False im Zusammenhang mit der Datenbank

blank=True/False im Zusammenhang mit der Formularvalidierung


11

Hier ist ein Beispiel für das Feld mit blank= Trueundnull=True

description = models.TextField (leer = True, null = True)

In diesem Fall :: blank = Trueteilt unserem Formular mit, dass es in Ordnung ist, das Beschreibungsfeld leer zu lassen

und

null = True: teilt unserer Datenbank mit, dass es in Ordnung ist, einen Nullwert in unser Datenbankfeld aufzunehmen und keinen Fehler anzugeben.


7
null = True

Dies bedeutet, dass für das zu füllende Feld keine Datenbankbeschränkung besteht. Sie können also ein Objekt mit dem Wert Null für das ausgefüllte Feld haben, das über diese Option verfügt.

blank = True

Bedeutet, dass es in Django-Formen keine Einschränkung der Validierung gibt. Wenn Sie also ein modelFormfür dieses Modell ausfüllen , können Sie das Feld mit dieser Option nicht ausfüllen .


7

Hier ist der Hauptunterschied von null=Trueund blank=True:

Der Standardwert von beiden nullund blankist False. Diese beiden Werte funktionieren auf Feldebene, dh ob wir ein Feld behalten möchten nulloder blank.

null=Truesetzt den Wert des Feldes auf NULLdh keine Daten. Dies gilt im Wesentlichen für den Spaltenwert der Datenbank.

date = models.DateTimeField(null=True)

blank=Truelegt fest, ob das Feld in Formularen benötigt wird. Dies umfasst den Administrator und Ihre eigenen benutzerdefinierten Formulare.

title = models.CharField(blank=True) // title can be kept blank. In der Datenbank ("")wird gespeichert. null=True blank=TrueDies bedeutet, dass das Feld unter allen Umständen optional ist.

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

6

Die Standardwerte für null und leer sind False.

Null: Es ist datenbankbezogen. Definiert, ob eine bestimmte Datenbankspalte Nullwerte akzeptiert oder nicht.

Leer: Es ist validierungsbezogen. Es wird während der Formularüberprüfung verwendet, wenn form.is_valid () aufgerufen wird.

Davon abgesehen ist es vollkommen in Ordnung, ein Feld mit null = True und blank = False zu haben. Auf Datenbankebene kann das Feld NULL sein, auf Anwendungsebene ist es jedoch ein Pflichtfeld.

Nun, wo die meisten Entwickler etwas falsch machen: Definieren von null = True für stringbasierte Felder wie CharField und TextField. Vermeiden Sie das. Andernfalls haben Sie zwei mögliche Werte für "keine Daten", nämlich " Keine" und eine leere Zeichenfolge. Zwei mögliche Werte für "keine Daten" sind redundant. Die Django-Konvention besteht darin, die leere Zeichenfolge zu verwenden, nicht NULL.


5

Wenn wir etwas in Django admin speichern, erfolgt die Validierung in zwei Schritten, auf Django-Ebene und auf Datenbankebene. Wir können keinen Text in einem Zahlenfeld speichern.

Die Datenbank hat den Datentyp NULL, es ist nichts. Wenn Django Spalten in der Datenbank erstellt, wird angegeben, dass diese nicht leer sein dürfen. Und wenn Sie versuchen, NULL zu speichern, wird der Datenbankfehler angezeigt.

Auch auf Django-Admin-Ebene sind standardmäßig alle Felder erforderlich. Sie können keine leeren Felder speichern. Django gibt einen Fehler aus.

Wenn Sie also ein leeres Feld speichern möchten, müssen Sie es auf Django- und Datenbankebene zulassen. blank = True - Ermöglicht ein leeres Feld im Admin-Bereich. null = True - Ermöglicht das Speichern von NULL in der Datenbankspalte.


5

Es gibt einen Punkt, an dem null=Truedies auch für ein CharFieldoder erforderlich wäre, TextFieldund dann ist für die Datenbank das uniqueFlag für die Spalte gesetzt.

Mit anderen Worten, wenn Sie ein eindeutiges Char / TextField in Django haben, müssen Sie Folgendes verwenden:

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

Bei nicht eindeutigem CharField oder TextField ist es besser, die null=TrueFelder zu überspringen, da sonst einige Felder als NULL festgelegt werden, während andere als "", und Sie müssen den Feldwert jedes Mal auf NULL überprüfen.


3

null ist für die Datenbank und leer ist für die Feldvalidierung, die Sie auf einer Benutzeroberfläche wie einem Textfeld anzeigen möchten, um den Nachnamen der Person zu erhalten. Wenn lastname = models.charfield (blank = true) , wurde der Benutzer nicht aufgefordert, den Nachnamen einzugeben, da dies jetzt das optionale Feld ist. Wenn lastname = models.charfield (null = true) , bedeutet dies, dass wenn dieses Feld keinen Wert vom Benutzer erhält, es als leere Zeichenfolge "" in der Datenbank gespeichert wird.


1

Die Bedeutung von null = True und blank = True im Modell hängt auch davon ab, wie diese Felder in der Formularklasse definiert wurden.

Angenommen, Sie haben die folgende Klasse definiert:

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

Wenn die Formularklasse wie folgt definiert wurde:

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'})
        }

Dann ist das Feld 'Name' nicht obligatorisch (aufgrund des Leerzeichens = True im Modell) und das Feld 'Adresse' ist obligatorisch (aufgrund des Leerzeichens = False im Modell).

Wenn die ClientForm-Klasse jedoch wie folgt definiert wurde:

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'}),
    )

Dann sind beide Felder ('Name' und 'Adresse') obligatorisch, "da deklarativ definierte Felder unverändert bleiben" ( https://docs.djangoproject.com/de/3.0/topics/forms/modelforms/ ). Das heißt, der Standardwert für das Attribut 'erforderlich' des Formularfelds ist True. Dazu müssen die Felder 'Name' und 'Adresse' ausgefüllt werden, auch wenn das Feld im Modell auf leer = True gesetzt wurde.



0

Diese Tabelle zeigt die Hauptunterschiede:

+--------------------------------------------------------------------+
| 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           |
+--------------------------------------------------------------------+

0

In sehr einfachen Worten :

Leer ist anders als null.

null ist rein datenbankbezogen , während leer validierungsbezogen ist (im Formular erforderlich) .

Wenn null=Trueja, wird Django store empty values as NULL in the database. Wenn ein Feld vorhanden ist blank=True, wird die Formularüberprüfung durchgeführt allow entry of an empty value. Wenn ein Feld leer = Falsch ist, wird das Feld benötigt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.