diferenciar null = True, blank = True en django

904

Cuando agregamos un campo de base de datos en django, generalmente escribimos:

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

Lo mismo se hace con ForeignKey, DecimalFieldetc. ¿Cuál es la diferencia básica en tener

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

con respecto a diferentes ( CharField, ForeignKey, ManyToManyField, DateTimeFieldcampos). ¿Cuáles son las ventajas / desventajas de usar 1/2/3?

user993563
fuente
8
Tiene buenas respuestas al respecto aquí: stackoverflow.com/questions/8159310/… y aquí: stackoverflow.com/questions/4384098/…
juliomalegria
2
Buena lectura: b-list.org/weblog/2006/jun/28/…
Salman von Abbas
Sí, también tengo este caso de uso con ForeignKeycon blank=True, pero sin null=True. Cuando se guarda el modelo, quiero "publicarlo" automáticamente creando una entrada publicada a partir de él. Por lo tanto, no puedo guardar nullen la base de datos, ya que cada modelo tiene que ser "publicado", pero quiero poder dejar el campo vacío en admin.
osa
Creo que puede estar interesado en [Guardar CharField vacío y anulable como nulo en lugar de como una cadena vacía] ( code.djangoproject.com/ticket/4136 ). Hay muchas discusiones sobre esto, y un problema muy práctico que puede encontrar (por ejemplo, desea agregar una URL de openid para cada usuario que puede ser nula y debería ser única).
ramwin

Respuestas:

1084

null=Trueestablece NULL(versus NOT NULL) en la columna en su base de datos. Los valores en blanco para los tipos de campo de Django, como DateTimeFieldo ForeignKeyse almacenarán como NULLen la base de datos.

blankdetermina si el campo será requerido en los formularios. Esto incluye el administrador y sus formularios personalizados. Si es blank=Trueasí, el campo no será obligatorio, mientras que si es Falseel campo no puede estar en blanco.

La combinación de ambos es muy frecuente porque, por lo general, si va a permitir que un campo esté en blanco en su formulario, también necesitará su base de datos para permitir NULLvalores para ese campo. La excepción es CharFieldsys TextField, que en Django nunca se guardan como NULL. Los valores en blanco se almacenan en la base de datos como una cadena vacía ( '').

Algunos ejemplos:

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

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

Obviamente, esas dos opciones no tienen sentido lógico de usar (aunque podría haber un caso de uso para null=True, blank=Falsesi desea que un campo siempre se requiera en formularios, opcional cuando se trata de un objeto a través de algo como el shell).

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

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

CHARy los TEXTtipos nunca se guardan como NULLDjango, por lo que null=Truees innecesario. Sin embargo, puede configurar manualmente uno de estos campos Nonepara forzar la configuración como NULL. Si tiene un escenario donde eso podría ser necesario, aún debe incluirlo null=True.

Chris Pratt
fuente
8
IntegrityErrorse genera cuando Django intenta guardar el registro en la base de datos. El usuario no necesita completar el campo, y ese es el problema porque a nivel de la base de datos no es nulo.
Chris Pratt
55
No, Chris está tratando de señalar por qué tener blank = True sin tener null = True causaría problemas en DateTimeField.
Vinod Kurup
44
NOTA para los usuarios de Oracle: No es cierto que " CHARy Django TEXTNUNCA los guarde NULL". Es cierto para la mayoría de los backends, pero Oracle forzará una cadena vacía a NULL, por lo que el backend Django Oracle es una excepción a la declaración anterior Django Docs
stv
10
@ChrisPratt Corrección menor a su publicación: CharFields puede guardarse como NULL en la base de datos (traduciéndose Noneen Python) si establece null = True. Los documentos incluso dicen que se evite establecer null = True porque permite dos tipos diferentes de valores "en blanco". Acabo de probar este comportamiento con Django 1.8 / MySQL 5.6
Edward D'Souza
3
es que nadie va a hablar de la combinación de: blank=True, null=False, default="something"?
Brian H.
125

Así es como los mapas blanky nullcampos ORM para 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)        

Los campos de la base de datos creados para PostgreSQL 9.4 son:

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

Los campos de la base de datos creados para MySQL 5.6 son:

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
)
usuario
fuente
41
En otras palabras, blankno tiene ningún efecto en la base de datos y nullcontrola si la columna de la base de datos permite NULLvalores. Esta respuesta es una forma muy larga de decir eso, y no proporciona ninguna información útil sobre blank.
Carl Meyer
19
@CarlMeyer: quería ver cómo se asignaría a la base de datos y compartirla, ya que ahorraría tiempo para que otros hicieran lo mismo. La teoría versus el ejemplo marcan la diferencia cuando se trata de asimilar y comprometerse con la memoria. De hecho, hice todo lo posible para agregar la asignación de una base de datos que no estaba usando. Gracias por el voto negativo. El número de personas que encontraron esto útil obviamente no está de acuerdo con usted.
usuario
55
Puede ser una respuesta útil si extrajo algunas conclusiones resumidas de los datos presentados, pero no creo que presentar un volcado de datos sin procesar sea una respuesta útil. En este caso, es en realidad una respuesta engañosa, ya que (sin más comentarios) implica que el efecto de ambos blanky nulldebe reflejarse en las columnas de la base, cuando en realidad blanksólo afecta el manejo de Python, no columnas de base de datos. Otros son libres de votar si lo encuentran útil; También es posible que las personas que son engañadas por una respuesta engañosa piensen que fue útil.
Carl Meyer
44
La respuesta aceptada que tiene casi 3 años explica todo en detalle. No tiene sentido repetir la misma información aquí.
usuario
47

Como se dijo en la referencia del campo modelo de Django: Enlace

Opciones de campo

Los siguientes argumentos están disponibles para todos los tipos de campo. Todos son opcionales.


null

Field.null

Si True, Django almacenará valores vacíos como NULLen la base de datos. Por defecto es False.

Evite usar nullen campos basados ​​en cadenas como CharFieldy TextFieldporque los valores de cadena vacíos siempre se almacenarán como cadenas vacías, no como NULL. Si un campo basado en cadenas tiene null=True, eso significa que tiene dos valores posibles para "sin datos": NULLy la cadena vacía. En la mayoría de los casos, es redundante tener dos valores posibles para "sin datos"; la convención de Django es usar la cadena vacía, no NULL.

Para los campos basados ​​en cadenas y no basados ​​en cadenas, también deberá establecer blank=Truesi desea permitir valores vacíos en los formularios, ya que el nullparámetro solo afecta el almacenamiento de la base de datos (consulte blank).

Nota

Cuando se utiliza el backend de la base de datos Oracle, el valor NULL se almacenará para denotar la cadena vacía independientemente de este atributo


blank

Field.blank

Si True, el campo puede estar en blanco. Por defecto es False.

Tenga en cuenta que esto es diferente de null. nullestá puramente relacionado con la base de datos, mientras que blankestá relacionado con la validación. Si un campo tiene blank=True, la validación del formulario permitirá la entrada de un valor vacío. Si un campo tiene blank=False, el campo será requerido.

DiogoLR
fuente
46

Es crucial comprender que las opciones en una definición de campo de modelo de Django tienen (al menos) dos propósitos: definir las tablas de la base de datos y definir el formato predeterminado y la validación de los formularios del modelo. (Digo "predeterminado" porque los valores siempre se pueden anular proporcionando un formulario personalizado). Algunas opciones afectan la base de datos, algunas opciones afectan a los formularios y otras afectan a ambos.

Cuando se trata de nully blank, otras respuestas ya han dejado en claro que la primera afecta la definición de la tabla de la base de datos y la segunda afecta la validación del modelo. Creo que la distinción puede hacerse aún más clara al ver los casos de uso para las cuatro configuraciones posibles:

  • null=False, blank=False: Esta es la configuración predeterminada y significa que el valor es obligatorio en todas las circunstancias.

  • null=True, blank=True: Esto significa que el campo es opcional en todas las circunstancias. (Sin embargo, como se indica a continuación, esta no es la forma recomendada de hacer que los campos basados ​​en cadenas sean opcionales).

  • null=False, blank=True: Esto significa que el formulario no requiere un valor, pero la base de datos sí. Hay varios casos de uso para esto:

    • El uso más común es para campos opcionales basados ​​en cadenas. Como se señala en la documentación , el idioma de Django es usar la cadena vacía para indicar un valor faltante. Si NULLtambién se permitiera, terminaría con dos formas diferentes de indicar un valor faltante.

    • Otra situación común es que desea calcular un campo automáticamente en función del valor de otro (en su save()método, por ejemplo). No desea que el usuario proporcione el valor de una forma (por lo tanto blank=True), pero sí desea que la base de datos haga cumplir que siempre se proporcione un valor ( null=False).

    • Otro uso es cuando desea indicar que a ManyToManyFieldes opcional. Debido a que este campo se implementa como una tabla separada en lugar de una columna de base de datos, no nulltiene sentido . Sin blankembargo, el valor de seguirá afectando a las formas, controlando si la validación tendrá éxito o no cuando no haya relaciones.

  • null=True, blank=False: Esto significa que el formulario requiere un valor pero la base de datos no. Esta puede ser la configuración que se usa con menos frecuencia, pero existen algunos casos de uso:

    • Es perfectamente razonable exigir a sus usuarios que siempre incluyan un valor, incluso si su lógica empresarial no lo requiere realmente. Después de todo, los formularios son solo una forma de agregar y editar datos. Es posible que tenga un código que genera datos que no necesita la misma validación estricta que desea exigir a un editor humano.

    • Otro caso de uso que he visto es cuando tiene uno ForeignKeypara el que no desea permitir la eliminación en cascada . Es decir, en el uso normal, la relación siempre debe estar allí ( blank=False), pero si lo que señala se elimina, no desea que este objeto también se elimine. En ese caso, puede usar null=Truee on_delete=models.SET_NULLimplementar un tipo simple de eliminación suave .

Kevin Christopher Henry
fuente
1
Esta es una respuesta perfecta, ¡todas las combinaciones posibles se explican de manera muy concisa!
RusI
1
Debería ser la respuesta aceptada.
Tom Mac
28

Es posible que tenga su respuesta, sin embargo, hasta el día de hoy es difícil juzgar si poner null = True o blank = True o ambos en un campo. Personalmente, creo que es bastante inútil y confuso proporcionar tantas opciones a los desarrolladores. Deje que manejen los nulos o espacios en blanco como quieran.

Sigo esta tabla, de Two Scoops of Django :ingrese la descripción de la imagen aquí

Tabla que muestra cuándo usar nulo o en blanco para cada tipo de campo

saran3h
fuente
26

Simplemente null=Truedefine que la base de datos debe aceptar NULLvalores, por otro lado, blank=Truedefine en la validación del formulario, este campo debe aceptar valores en blanco o no (si blank=Trueacepta el formulario sin un valor en ese campo y blank=False[valor predeterminado] en la validación del formulario, se mostrará Este campo es un error obligatorio .

null=True/False relacionado con la base de datos

blank=True/False relacionado con la validación de formularios

Ranju R
fuente
11

Aquí hay un ejemplo del campo con blank= Trueynull=True

descripción = modelos.TextField (en blanco = verdadero, nulo = verdadero)

En este caso:: blank = Truele dice a nuestro formulario que está bien dejar el campo de descripción en blanco

y

null = True: le dice a nuestra base de datos que está bien registrar un valor nulo en nuestro campo db y no dar un error.

Stryker
fuente
7
null = True

Significa que no hay restricción de la base de datos para que el campo se complete, por lo que puede tener un objeto con valor nulo para el relleno que tiene esta opción.

blank = True

Significa que no hay restricción de validación en los formularios de django. así que cuando complete un modelFormpara este modelo, puede dejar el campo con esta opción sin completar.

Milad Khodabandehloo
fuente
7

Aquí, es la principal diferencia de null=Truey blank=True:

El valor predeterminado de ambos nully blankes False. Ambos valores funcionan a nivel de campo, es decir, si queremos mantener un campo nullo blank.

null=Trueestablecerá el valor del campo en NULL, es decir, sin datos. Básicamente es para el valor de la columna de bases de datos.

date = models.DateTimeField(null=True)

blank=Truedetermina si el campo será requerido en los formularios. Esto incluye el administrador y sus propios formularios personalizados.

title = models.CharField(blank=True) // title can be kept blank. En la base de datos ("")se almacenará. null=True blank=TrueEsto significa que el campo es opcional en todas las circunstancias.

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

Los valores predeterminados de nulo y en blanco son falsos.

Nulo: está relacionado con la base de datos. Define si una columna de base de datos determinada aceptará valores nulos o no.

En blanco: está relacionado con la validación. Se usará durante la validación de formularios, al llamar a form.is_valid ().

Dicho esto, está perfectamente bien tener un campo con nulo = Verdadero y en blanco = Falso. Es decir, en el nivel de la base de datos, el campo puede ser NULL, pero en el nivel de la aplicación es un campo obligatorio.

Ahora, donde la mayoría de los desarrolladores se equivocan: Definir null = True para campos basados ​​en cadenas como CharField y TextField. Evita hacer eso. De lo contrario, terminará teniendo dos valores posibles para "sin datos", es decir: Ninguno y una cadena vacía. Tener dos valores posibles para "sin datos" es redundante. La convención de Django es usar la cadena vacía, no NULL.

sharif_42
fuente
5

Cuando guardamos algo en el administrador de Django, se realiza la validación de dos pasos, en el nivel de Django y en el nivel de la base de datos. No podemos guardar texto en un campo numérico.

La base de datos tiene el tipo de datos NULL, no es nada. Cuando Django crea columnas en la base de datos, especifica que no pueden estar vacías. Y si intenta guardar NULL, obtendrá el error de la base de datos.

También en el nivel Django-Admin, todos los campos son obligatorios por defecto, no puede guardar el campo en blanco, Django le arrojará un error.

Por lo tanto, si desea guardar el campo en blanco, debe permitirlo en el nivel de Django y Base de datos. blank = True - permitirá un campo vacío en el panel de administración null = True - permitirá guardar NULL en la columna de la base de datos.

Yuriy Kots
fuente
5

Hay un punto en el null=Trueque sería necesario incluso en un CharFieldo TextFieldy es cuando la base de datos tiene la uniquebandera establecida para la columna.

En otras palabras, si tiene un Char / TextField único en Django, deberá usar esto:

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

Para CharField o TextField no únicos, será mejor omitirlo; de lo null=Truecontrario, algunos campos se establecerán como NULL mientras que otros como "", y deberá verificar el valor del campo para NULL cada vez.

Nitin Nain
fuente
3

nulo es para la base de datos y en blanco es para la validación de campos que desea mostrar en la interfaz de usuario como el campo de texto para obtener el apellido de la persona. Si lastname = models.charfield (blank = true) no le pidió al usuario que ingrese el apellido ya que este es el campo opcional ahora. Si lastname = models.charfield (null = true) significa que si este campo no obtiene ningún valor del usuario, se almacenará en la base de datos como una cadena vacía "".

Tabish
fuente
1

El significado de null = True y blank = True en el modelo también depende de cómo se definieron estos campos en la clase de formulario.

Supongamos que ha definido la siguiente clase:

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

Si la clase de formulario se ha definido así:

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

Entonces, el campo 'nombre' no será obligatorio (debido al espacio en blanco = Verdadero en el modelo) y el campo 'dirección' será obligatorio (debido al espacio en blanco = Falso en el modelo).

Sin embargo, si la clase ClientForm se ha definido así:

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

Entonces, ambos campos ('nombre' y 'dirección') serán obligatorios, "ya que los campos definidos declarativamente se dejan como están" ( https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ ) , es decir, el valor predeterminado para el atributo 'requerido' del campo de formulario es True y esto requerirá que se llenen los campos 'nombre' y 'dirección', incluso si, en el modelo, el campo se ha configurado en blanco = True.

Carlos Ribeiro
fuente
0

La siguiente tabla muestra las principales diferencias:

+--------------------------------------------------------------------+
| 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           |
+--------------------------------------------------------------------+
lavee_singh
fuente
0

En palabras muy simples ,

En blanco es diferente de nulo.

nulo está puramente relacionado con la base de datos , mientras que el blanco está relacionado con la validación (requerido en el formulario) .

Si null=True, Django lo hará store empty values as NULL in the database. Si un campo tiene blank=True, la validación del formulario lo hará allow entry of an empty value. Si un campo tiene en blanco = Falso, el campo será obligatorio.

Yash
fuente