¿Cuál es la diferencia entre null=True y en blanco=True en Django?
Cuando agregamos un campo modelo en Django generalmente escribimos:
models.CharField(max_length=100, null=True, blank=True)
Lo mismo se hace con ForeignKey
, DecimalField
etc. ¿Cuál es la diferencia básica entre:
null=True
soloblank=True
solonull=True
yblank=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?
null=True
conjuntos NULL
(versus NOT NULL
) en la columna de su base de datos. Los valores en blanco para los tipos de campos de Django, como DateTimeField
o, ForeignKey
se almacenarán como NULL
en la base de datos.
blank
determina si el campo será obligatorio en los formularios. Esto incluye el administrador y sus formularios personalizados. En caso blank=True
contrario, el campo no será obligatorio, mientras que si lo es, False
el 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 NULL
valores para ese campo. La excepción son CharField
s y TextField
s, 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=False
desea 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
CHAR
y TEXT
los tipos nunca se guardan como NULL
lo hace Django, por lo que null=True
es innecesario. Sin embargo, puede configurar manualmente uno de estos campos para None
forzar su configuración como NULL
. Si tiene un escenario en el que esto podría ser necesario, aún así debe incluir null=True
.
Así es como los mapas blank
y null
campos 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
)
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 null
y 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
NULL
también estuviera permitido, terminaría con dos formas diferentes de indicar un valor faltante. (Sin embargo, si el campo también esunique
, deberá usarlonull=True
para 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 tantoblank=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
ManyToManyField
es opcional. Debido a que este campo se implementa como una tabla separada en lugar de una columna de base de datos,null
no tiene sentido . Sin embargo, el valor deblank
seguirá 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
ForeignKey
en 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 utilizarnull=True
yon_delete=models.SET_NULL
implementar un tipo simple de eliminación temporal .
Es posible que tenga la respuesta; sin embargo, hasta el día de hoy es difícil juzgar si colocar null=True
o blank=True
ambas 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 :