differenziare null = True, blank = True in django


904

Quando aggiungiamo un campo di database in django generalmente scriviamo:

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

Lo stesso si fa con ForeignKey, DecimalFieldecc. Qual è la differenza fondamentale nell'avere

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

rispetto a differenti ( CharField, ForeignKey, ManyToManyField, DateTimeFieldcampi). Quali sono i vantaggi / gli svantaggi dell'utilizzo di 1/2/3?




Sì, ho anche questo caso d'uso ForeignKeycon blank=True, ma senza null=True. Quando il modello viene salvato, voglio "pubblicarlo" automaticamente creando una voce pubblicata da esso. Quindi non posso salvare nullnel database, poiché ogni modello deve essere "pubblicato", ma voglio poter lasciare il campo vuoto in admin.
osa,

Penso che potresti essere interessato a [Salva CharField vuoto, nullable come null anziché come stringa vuota] ( code.djangoproject.com/ticket/4136 ). Ci sono molte discussioni su questo e un problema molto pratico che potresti incontrare (ad es. Vuoi aggiungere un URL openid per ogni utente che può essere nullo e dovrebbe essere unico).
Ramwin,

Risposte:


1084

null=Trueimposta NULL(contro NOT NULL) sulla colonna nel tuo DB. I valori vuoti per i tipi di campo Django come DateTimeFieldo ForeignKeyverranno memorizzati come NULLnel DB.

blankdetermina se il campo sarà richiesto nei moduli. Ciò include l'amministratore e i tuoi moduli personalizzati. In blank=Truetal caso il campo non sarà richiesto, mentre in questo caso Falseil campo non può essere vuoto.

La combinazione dei due è così frequente perché in genere se si consente a un campo di essere vuoto nel modulo, sarà necessario anche il database per consentire i NULLvalori per quel campo. L'eccezione è CharFields e TextFields, che in Django non vengono mai salvati come NULL. I valori vuoti sono memorizzati nel DB come una stringa vuota ( '').

Alcuni esempi:

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

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

Ovviamente, queste due opzioni non hanno senso logico da usare (anche se potrebbe esserci un caso d'uso null=True, blank=Falsese si desidera che un campo sia sempre richiesto nei moduli, facoltativo quando si tratta di un oggetto attraverso qualcosa come la shell).

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

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

CHARe i TEXTtipi non vengono mai salvati come NULLda Django, quindi null=Truenon è necessario. Tuttavia, è possibile impostare manualmente uno di questi campi Noneper forzarlo come NULL. Se hai uno scenario in cui ciò potrebbe essere necessario, dovresti comunque includerlo null=True.


8
IntegrityErrorviene generato quando Django tenta di salvare il record nel database. Il campo non deve essere compilato dall'utente e questo è il problema perché a livello di database non è nullo.
Chris Pratt,

5
No, Chris sta cercando di evidenziare perché avere blank = True senza avere null = True causerebbe problemi in un DateTimeField.
Vinod Kurup,

4
NOTA per gli utenti Oracle: non è vero che " CHARe TEXTnon vengono MAI salvati come NULLda Django". È vero per la maggior parte dei backend, ma Oracle imporrà una stringa vuota a NULL, quindi il backend Oracle Django è un'eccezione alla precedente dichiarazione Django Docs
stv

10
@ChrisPratt Correzione minore per il tuo post: CharFields può essere salvato come NULL nel database (traducendolo Nonein Python) se imposti null = True. I documenti sostengono addirittura di evitare di impostare null = True perché consente due diversi tipi di valori "vuoti". Ho appena testato questo comportamento con Django 1.8 / MySQL 5.6
Edward D'Souza il

3
è nessuno sta per parlare della combinazione di: blank=True, null=False, default="something"?
Brian H.

125

Ecco come le mappe blanke i nullcampi ORM per 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)        

I campi del database creati per PostgreSQL 9.4 sono:

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

I campi del database creati per MySQL 5.6 sono:

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
In altre parole, blanknon ha alcun effetto sul database e nullcontrolla se la colonna del database consente NULLvalori. Questa risposta è un modo molto lungo per dirlo e non fornisce alcuna informazione utile a riguardo blank.
Carl Meyer,

19
@CarlMeyer: Volevo vedere come sarebbe stato mappato al database e condiviso poiché avrebbe risparmiato tempo per gli altri a fare lo stesso. Teoria vs esempio fanno la differenza quando si tratta di assimilare e impegnarsi nella memoria. In effetti, ho fatto di tutto per aggiungere la mappatura per un database che non stavo usando. Grazie per il downvote. Il numero di persone che l'hanno trovato utile ovviamente non è d'accordo con te.
utente

5
Potrebbe essere una risposta utile se hai tratto alcune conclusioni di riepilogo dai dati presentati, ma non penso che presentare una discarica di dati grezzi sia una risposta utile. In questo caso è in realtà una risposta fuorviante, poiché (senza ulteriori commenti) implica che l'effetto di entrambi blanke nulldovrebbe riflettersi nelle colonne del database, quando in realtà blankinteressa solo la gestione di Python, non le colonne del database. Altri sono liberi di votare se lo hanno trovato utile; è anche possibile per le persone ingannate da una risposta fuorviante pensare che sia utile.
Carl Meyer,

4
La risposta accettata che ha quasi 3 anni spiega tutto in dettaglio. Non ha senso ripetere le stesse informazioni qui.
utente

47

Come detto nel riferimento al campo del modello Django: Link

Opzioni sul campo

I seguenti argomenti sono disponibili per tutti i tipi di campo. Tutti sono opzionali.


null

Field.null

Se True, Django memorizzerà valori vuoti come NULLnel database. L'impostazione predefinita è False.

Evitare di utilizzare nullsu campi basati su stringhe come CharFielde TextFieldperché i valori di stringa vuoti verranno sempre memorizzati come stringhe vuote, non come NULL. Se un campo basato su stringa ha null=True, ciò significa che ha due possibili valori per "nessun dato": NULLe la stringa vuota. Nella maggior parte dei casi, è ridondante avere due possibili valori per "nessun dato"; la convenzione Django è di usare la stringa vuota, no NULL.

Per i campi basati su stringhe e non basati su stringhe, dovrai anche impostare blank=Truese desideri consentire valori vuoti nei moduli, poiché il nullparametro influisce solo sull'archiviazione del database (vedi blank).

Nota

Quando si utilizza il back-end del database Oracle, il valore NULL verrà archiviato per indicare la stringa vuota indipendentemente da questo attributo


blank

Field.blank

Se True, il campo può essere vuoto. L'impostazione predefinita è False.

Si noti che questo è diverso da null. nullè puramente relativo al database, mentre blankè relativo alla validazione. Se un campo ha blank=True, la convalida del modulo consentirà l'immissione di un valore vuoto. Se un campo ha blank=False, il campo sarà richiesto.


46

È fondamentale capire che le opzioni in una definizione del campo del modello Django servono (almeno) a due scopi: definire le tabelle del database e definire il formato predefinito e la convalida dei moduli del modello. (Dico "predefinito" perché i valori possono sempre essere sovrascritti fornendo un modulo personalizzato.) Alcune opzioni influiscono sul database, alcune opzioni sui moduli e altre su entrambi.

Per quanto riguarda nulle blank, altre risposte hanno già chiarito che il primo influisce sulla definizione della tabella del database e il secondo sulla convalida del modello. Penso che la distinzione possa essere resa ancora più chiara osservando i casi d'uso per tutte e quattro le possibili configurazioni:

  • null=False, blank=False: Questa è la configurazione predefinita e significa che il valore è richiesto in tutte le circostanze.

  • null=True, blank=True: Ciò significa che il campo è facoltativo in tutte le circostanze. (Come indicato di seguito, tuttavia, questo non è il modo consigliato per rendere facoltativi i campi basati su stringhe.)

  • null=False, blank=True: Ciò significa che il modulo non richiede un valore ma lo fa il database. Esistono diversi casi d'uso per questo:

    • L'uso più comune è per i campi facoltativi basati su stringhe. Come notato nella documentazione , il linguaggio di Django è usare la stringa vuota per indicare un valore mancante. Se NULLfosse consentito, si finirebbe con due modi diversi per indicare un valore mancante.

    • Un'altra situazione comune è che vuoi calcolare automaticamente un campo in base al valore di un altro (nel tuo save()metodo, diciamo). Non si desidera che l'utente fornisca il valore in un modulo (quindi blank=True), ma si desidera che il database imponga che venga sempre fornito un valore ( null=False).

    • Un altro uso è quando si desidera indicare che a ManyToManyFieldè facoltativo. Perché questo campo è implementato come una tabella separata piuttosto che una colonna del database, non ha nullsenso . Il valore di blankinfluenzerà comunque le forme, controllando se la validazione avrà successo o meno quando non ci sono relazioni.

  • null=True, blank=False: Ciò significa che il modulo richiede un valore ma il database no. Questa potrebbe essere la configurazione usata più di rado, ma ci sono alcuni casi d'uso:

    • È perfettamente ragionevole richiedere agli utenti di includere sempre un valore anche se non è effettivamente richiesto dalla logica aziendale. Dopo tutto, i moduli sono solo un modo per aggiungere e modificare i dati. Potresti avere un codice che sta generando dati che non richiedono la stessa rigorosa convalida che desideri richiedere a un editor umano.

    • Un altro caso d'uso che ho visto è quando hai un ForeignKeyper il quale non desideri consentire la cancellazione in cascata . Cioè, nell'uso normale la relazione dovrebbe sempre essere lì ( blank=False), ma se la cosa a cui punta sembra essere cancellata, non si desidera eliminare anche questo oggetto. In tal caso è possibile utilizzare null=Truee on_delete=models.SET_NULLimplementare un tipo semplice di eliminazione soft .


1
Questa è una risposta perfetta, tutte le possibili combinazioni sono spiegate in modo molto conciso!
RusI

1
Dovrebbe essere la risposta accettata.
Tom Mac

28

Potresti avere la tua risposta tuttavia fino ad oggi è difficile giudicare se inserire null = Vero o vuoto = Vero o entrambi in un campo. Personalmente penso che sia abbastanza inutile e confuso fornire così tante opzioni agli sviluppatori. Lasciate che gestiscano i valori nulli o vuoti come vogliono.

Seguo questa tabella, da Two Scoops of Django :inserisci qui la descrizione dell'immagine

Tabella che mostra quando utilizzare null o vuoto per ciascun tipo di campo


26

null=TrueDefinisce semplicemente che il database deve accettare i NULLvalori, d'altra parte blank=Truedefinisce sulla convalida del modulo questo campo dovrebbe accettare valori vuoti o meno (se blank=Trueaccetta il modulo senza un valore in quel campo e blank=False[valore predefinito] sulla convalida del modulo mostrerà Questo campo è richiesto errore.

null=True/False relativo al database

blank=True/False relativo alla convalida del modulo


11

Ecco un esempio del campo con blank= Trueenull=True

descrizione = modelli.TextField (vuoto = Vero, null = Vero)

In questo caso:: blank = Trueindica al nostro modulo che è ok lasciare vuoto il campo della descrizione

e

null = True: dice al nostro database che va bene registrare un valore nullo nel nostro campo db e non dare un errore.


7
null = True

Significa che non esiste alcun vincolo del database per il campo da compilare, quindi è possibile avere un oggetto con valore null per il riempimento che ha questa opzione.

blank = True

Significa che non esiste alcun vincolo di convalida nelle forme di django. quindi quando si riempie un modelFormper questo modello è possibile lasciare il campo con questa opzione non compilata .


7

Ecco, la differenza principale di null=Truee blank=True:

Il valore predefinito di entrambi nulled blankè Falso. Entrambi questi valori funzionano a livello di campo, cioè se vogliamo mantenere un campo nulloblank .

null=Trueimposterà il valore del campo su NULLie, nessun dato. Fondamentalmente è per il valore della colonna dei database.

date = models.DateTimeField(null=True)

blank=Truedetermina se il campo sarà richiesto nei moduli. Ciò include l'amministratore e i tuoi moduli personalizzati.

title = models.CharField(blank=True) // title can be kept blank. Nel database ("")verrà memorizzato. null=True blank=TrueCiò significa che il campo è facoltativo in tutte le circostanze.

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

I valori predefiniti di null e blank sono False.

Null: è relativo al database. Definisce se una determinata colonna del database accetterà o meno valori null.

Vuoto: è relativo alla convalida. Verrà utilizzato durante la convalida dei moduli, quando si chiama form.is_valid ().

Detto questo, è perfettamente bene avere un campo con null = True e blank = False. Significato a livello di database il campo può essere NULL, ma a livello di applicazione è un campo obbligatorio.

Ora, dove la maggior parte degli sviluppatori sbaglia: definizione di null = True per campi basati su stringhe come CharField e TextField. Evita di farlo. Altrimenti, si avranno due possibili valori per "nessun dato", ovvero: Nessuno e una stringa vuota. Avere due possibili valori per "nessun dato" è ridondante. La convenzione di Django consiste nell'utilizzare la stringa vuota, non NULL.


5

Quando salviamo qualcosa nell'amministratore di Django, si verificano due passaggi di convalida, a livello di Django e a livello di database. Non è possibile salvare il testo in un campo numerico.

Il database ha il tipo di dati NULL, non è niente. Quando Django crea colonne nel database, specifica che non possono essere vuote. E se proverai a salvare NULL otterrai l'errore del database.

Anche a livello di Django-Admin, tutti i campi sono obbligatori per impostazione predefinita, non è possibile salvare un campo vuoto, Django ti genererà un errore.

Quindi, se vuoi salvare un campo vuoto, devi permetterlo a livello di Django e Database. blank = True - consentirà il campo vuoto nel pannello di amministrazione null = True - consentirà di salvare NULL nella colonna del database.


5

C'è un punto in cui null=Truesarebbe necessario anche su un CharFieldo TextFielded è quando il database ha il uniqueflag impostato per la colonna.

In altre parole, se hai un Char / TextField unico in Django, dovrai usare questo:

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

Per CharField o TextField non univoci, ti conviene saltare i null=Truecampi, altrimenti alcuni campi verranno impostati come NULL mentre altri come "" e dovrai controllare il valore del campo per NULL ogni volta.


3

null è per il database e vuoto per la convalida dei campi che si desidera mostrare sull'interfaccia utente come campo di testo per ottenere il cognome della persona. Se lastname = models.charfield (blank = true) non ha chiesto all'utente di inserire il cognome in quanto questo è il campo opzionale ora. Se lastname = models.charfield (null = true) significa che se questo campo non ottiene alcun valore dall'utente, verrà archiviato nel database come una stringa vuota "".


1

Il significato di null = True e blank = True nel modello dipende anche da come questi campi sono stati definiti nella classe del modulo.

Supponiamo di aver definito la seguente classe:

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

Se la classe del modulo è stata definita in questo modo:

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

Quindi, il campo "nome" non sarà obbligatorio (a causa del vuoto = Vero nel modello) e il campo "indirizzo" sarà obbligatorio (a causa del vuoto = Falso nel modello).

Tuttavia, se la classe ClientForm è stata definita in questo modo:

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

Quindi, entrambi i campi ("nome" e "indirizzo") saranno obbligatori " , poiché i campi definiti in modo dichiarativo vengono lasciati così come sono" ( https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ ) , ovvero l'attributo predefinito per l'attributo "obbligatorio" del campo modulo è Vero e ciò richiederà che i campi "nome" e "indirizzo" siano compilati, anche se, nel modello, il campo è stato impostato su vuoto = Vero.



0

La tabella seguente mostra le principali differenze:

+--------------------------------------------------------------------+
| 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 parole molto semplici ,

Lo spazio vuoto è diverso da null.

null è puramente relativo al database , mentre il vuoto è relativo alla convalida (richiesto nel modulo) .

Se lo null=Truefarà Django store empty values as NULL in the database. Se un campo ha blank=True, sarà la convalida del modulo allow entry of an empty value. Se un campo ha vuoto = Falso, il campo sarà richiesto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.