¿Cuál es la diferencia entre null=True y en blanco=True en Django?

Resuelto user993563 asked hace 12 años • 30 respuestas

Cuando agregamos un campo modelo 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 entre:

  1. null=Truesolo
  2. blank=Truesolo
  3. null=Trueyblank=True

con respecto a diferentes campos ( CharField, ForeignKey, ManyToManyField, DateTimeField)? ¿Cuáles son las ventajas/desventajas de utilizar la opción 1, 2 o 3?

user993563 avatar Dec 23 '11 03:12 user993563
Aceptado

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

blankdetermina si el campo será obligatorio en los formularios. Esto incluye el administrador y sus formularios personalizados. En caso blank=Truecontrario, el campo no será obligatorio, mientras que si lo es, Falseel campo no puede estar en blanco.

La combinación de los dos es muy frecuente porque normalmente, si va a permitir que un campo esté en blanco en su formulario, también necesitará que su base de datos permita NULLvalores para ese campo. La excepción son CharFields y TextFields, 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, no tiene sentido lógico usar esas dos opciones (aunque podría haber un caso de uso si null=True, blank=Falsedesea que un campo siempre sea obligatorio en los 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 TEXTlos tipos nunca se guardan como NULLlo hace Django, por lo que null=Truees innecesario. Sin embargo, puede configurar manualmente uno de estos campos para Noneforzar su configuración como NULL. Si tiene un escenario en el que esto podría ser necesario, aún así debe incluir null=True.

Chris Pratt avatar Dec 22 '2011 20:12 Chris Pratt

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
)
user avatar Feb 16 '2014 14:02 user

Es crucial comprender que las opciones en la definición de campo del modelo Django sirven (al menos) para 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 los formularios y otras afectan a ambos.

Cuando se trata de nully blank, otras respuestas ya han dejado 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 se puede hacer aún más clara al observar 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 indica en la documentación , el modismo de Django consiste en utilizar una cadena vacía para indicar un valor faltante. Si NULLtambién estuviera permitido, terminaría con dos formas diferentes de indicar un valor faltante. (Sin embargo, si el campo también es unique, deberá usarlo null=Truepara evitar que varias cadenas vacías no superen la verificación de unicidad).

    • 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 en un formulario (por lo tanto blank=True), pero sí desea que la base de datos exija que siempre se proporcione un valor ( null=False).

    • Otro uso es cuando quieres 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, nullno tiene sentido . Sin embargo, el valor de blankseguirá afectando 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 utilizada 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. Después de todo, los formularios son sólo una forma de agregar y editar datos. Es posible que tenga un código que genere datos que no necesite la misma validación estricta que desea exigir de un editor humano.

    • Otro caso de uso que he visto es cuando tienes un archivo ForeignKeyen el que no deseas permitir la eliminación en cascada . Es decir, en uso normal la relación siempre debería estar ahí ( blank=False), pero si lo que apunta se elimina, no querrás que este objeto se elimine también. En ese caso, puede utilizar null=Truey on_delete=models.SET_NULLimplementar un tipo simple de eliminación temporal .

Kevin Christopher Henry avatar Dec 01 '2017 09:12 Kevin Christopher Henry

Es posible que tenga la respuesta; sin embargo, hasta el día de hoy es difícil juzgar si colocar null=Trueo blank=Trueambas cosas en un campo. Personalmente, creo que es bastante inútil y confuso ofrecer tantas opciones a los desarrolladores. Deje que manejen los valores 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 avatar Sep 07 '2018 07:09 saran3h