1138 votes

Quelle est la différence entre null=True et blank=True dans Django ?

Lorsque nous ajoutons un champ de base de données dans django, nous écrivons généralement :

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

La même chose est faite avec ForeignKey , DecimalField etc. Quelle est la différence fondamentale entre le fait d'avoir

  1. null=True sólo
  2. blank=True sólo
  3. null=True , blank=True

par rapport à différents ( CharField , ForeignKey , ManyToManyField , DateTimeField ). Quels sont les avantages/inconvénients de l'utilisation de 1/2/3 ?

12 votes

Vous avez de belles réponses à ce sujet ici : stackoverflow.com/questions/8159310/ et ici : stackoverflow.com/questions/4384098/

4 votes

0 votes

Oui, j'ai aussi ce cas d'utilisation avec ForeignKey con blank=True mais sans null=True . Lorsque le modèle est enregistré, je veux le "publier" automatiquement en créant une entrée publiée à partir de celui-ci. Je ne peux donc pas sauvegarder null dans la base de données, car chaque modèle doit être "publié", mais je veux pouvoir laisser le champ vide dans l'administration.

1362voto

Chris Pratt Points 53859

null=True fixe NULL (contre NOT NULL ) sur la colonne dans votre BD. Les valeurs vides pour les types de champs Django tels que DateTimeField ou ForeignKey sera stocké en tant que NULL dans la BD.

blank détermine si le champ sera obligatoire dans les formulaires. Cela inclut l'administrateur et vos formulaires personnalisés. Si blank=True alors le champ ne sera pas obligatoire, alors que s'il s'agit de False le champ ne peut pas être vide.

La combinaison des deux est très fréquente car, en général, si vous autorisez un champ à être vide dans votre formulaire, il faut aussi que votre base de données autorise NULL pour ce champ. L'exception est CharField et TextField qui, dans Django, sont jamais enregistré comme NULL . Les valeurs vides sont stockées dans la BD comme une chaîne vide ( '' ).

Quelques exemples :

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

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

Évidemment, l'utilisation de ces deux options n'a pas de sens logique (bien qu'il puisse y avoir un cas d'utilisation pour l'option null=True, blank=False si vous voulez qu'un champ soit toujours obligatoire dans les formulaires, facultatif lorsqu'on traite un objet par le biais de quelque chose comme le 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 ne sont jamais enregistrés en tant que NULL par Django, donc null=True n'est pas nécessaire. Cependant, vous pouvez définir manuellement l'un de ces champs comme étant None pour le forcer à devenir NULL . Si vous avez un scénario où cela pourrait être nécessaire, vous devriez quand même inclure null=True .

0 votes

Dans votre explication, models.DateTimeField(blank=True) vous dites que si ce champ DateTimeField est laissé vide, une IntegrityError est levée. Mais je pensais que blank=True signifiait que le champ ne devait pas être rempli par l'utilisateur, alors pourquoi une IntegrityError ?

8 votes

IntegrityError est soulevé lorsque Django tente d'enregistrer l'enregistrement dans la base de données. Le champ n'a pas besoin d'être rempli par l'utilisateur, et c'est là le problème, car au niveau de la base de données, il n'est pas nul.

2 votes

Je pense que user798719 fait référence à la valeur de blank, qui devrait être False au lieu de True dans votre exemple : models.DateTimeField(blank=False) # raises IntegrityError if blank

142voto

buffer Points 2261

Voici comment l'ORM fait correspondre blank & null champs pour 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)        

Les champs de la base de données créés pour PostgreSQL 9.4 sont :

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

Les champs de la base de données créés pour MySQL 5.6 sont :

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
)

58 votes

En d'autres termes, blank n'a aucun effet sur la base de données, et null contrôle si la colonne de la base de données permet NULL valeurs. Cette réponse est une façon vraiment longue de dire cela, et n'apporte aucune information utile sur blank .

21 votes

@CarlMeyer : Je voulais voir comment cela correspondrait à la base de données et partagé puisque cela ferait gagner du temps à d'autres personnes de faire de même. La théorie et l'exemple font une différence lorsqu'il s'agit d'assimiler et de mémoriser. En fait, j'ai fait l'effort d'ajouter le mappage pour une base de données que je n'utilisais pas. Merci pour le vote négatif. Le nombre de personnes qui ont trouvé cet article utile ne sont manifestement pas d'accord avec vous.

6 votes

La réponse pourrait être utile si vous tiriez des conclusions sommaires des données présentées, mais je ne pense pas que la présentation d'une décharge de données brutes soit une réponse utile. Dans ce cas, il s'agit en fait d'une réponse trompeuse, puisque (sans autre commentaire) elle implique que l'effet des deux facteurs suivants blank y null devrait être reflétée dans les colonnes de la base de données, alors qu'en fait blank n'affecte que la manipulation de Python, pas les colonnes de la base de données. Les autres sont libres d'upvoter s'ils ont trouvé cela utile ; il est également possible pour les personnes qui sont induites en erreur par une réponse trompeuse de pensez à c'était utile.

93voto

Il est crucial de comprendre que les options d'une définition de champ de modèle Django servent (au moins) deux objectifs : définir les tables de la base de données, et définir le format et la validation par défaut des formulaires du modèle. (Je dis "par défaut" car les valeurs peuvent toujours être remplacées en fournissant un formulaire personnalisé). Certaines options affectent la base de données, d'autres les formulaires, et d'autres encore les deux.

Lorsqu'il s'agit de null y blank Les autres réponses ont déjà précisé que la première concerne la définition des tables de la base de données et la seconde la validation du modèle. Je pense que la distinction peut être rendue encore plus claire en examinant les cas d'utilisation pour les quatre configurations possibles :

  • null=False , blank=False : Il s'agit de la configuration par défaut et cela signifie que la valeur est requise en toutes circonstances.

  • null=True , blank=True : Cela signifie que le champ est facultatif en toutes circonstances. (Comme indiqué ci-dessous, cependant, il s'agit d'un no la manière recommandée de rendre facultatifs les champs basés sur des chaînes de caractères).

  • null=False , blank=True : Cela signifie que le formulaire n'a pas besoin d'une valeur mais que la base de données en a besoin. Il existe un certain nombre de cas d'utilisation pour cela :

    • L'utilisation la plus courante est celle des champs facultatifs de type chaîne de caractères. Comme noté dans la documentation Dans le cas de Django, l'idiome est d'utiliser la chaîne vide pour indiquer une valeur manquante. Si NULL était également autorisée, vous vous retrouveriez avec deux façons différentes d'indiquer une valeur manquante.

    • Une autre situation courante est que vous souhaitez calculer automatiquement un champ en fonction de la valeur d'un autre (dans votre fichier save() méthode, disons). Vous ne voulez pas que l'utilisateur fournisse la valeur dans un formulaire (d'où l'expression blank=True ), mais vous voulez que la base de données impose qu'une valeur soit toujours fournie ( null=False ).

    • Une autre utilisation est celle qui consiste à indiquer qu'une ManyToManyField est facultatif. Parce que ce champ est implémenté comme une table séparée plutôt que comme une colonne de base de données, null n'a pas de sens . La valeur de blank affectera quand même les formulaires, en contrôlant si la validation réussira ou non lorsqu'il n'y a pas de relations.

  • null=True , blank=False : Cela signifie que le formulaire requiert une valeur mais que la base de données ne le fait pas. C'est peut-être la configuration la moins utilisée, mais elle peut être utilisée dans certains cas :

    • Il est tout à fait raisonnable d'exiger de vos utilisateurs qu'ils incluent toujours une valeur, même si votre logique commerciale ne l'exige pas. Après tout, les formulaires ne sont qu'un moyen parmi d'autres d'ajouter et de modifier des données. Il se peut que votre code génère des données qui ne nécessitent pas la même validation rigoureuse que celle que vous voulez exiger d'un éditeur humain.

    • Un autre cas d'utilisation que j'ai vu est lorsque vous avez une ForeignKey pour lesquels vous ne souhaitez pas autoriser suppression de la cascade . C'est-à-dire que, dans une utilisation normale, la relation devrait toujours être présente ( blank=False ), mais si l'objet vers lequel il pointe est supprimé, vous ne voulez pas que cet objet soit également supprimé. Dans ce cas, vous pouvez utiliser null=True y on_delete=models.SET_NULL pour mettre en œuvre un type simple de suppression douce .

54voto

DiogoLR Points 1

Comme indiqué dans la référence Django Model Field : Lien

Options de champ

Les arguments suivants sont disponibles pour tous les types de champs. Tous sont facultatifs.

null

Field.null

Si True Django stockera les valeurs vides comme NULL dans la base de données. La valeur par défaut est False .

Évitez d'utiliser null sur les champs basés sur des chaînes de caractères tels que CharField et TextField parce que les valeurs de chaînes vides seront toujours stockées comme vides. vides, et non comme NULL . Si un champ basé sur une chaîne de caractères a null=True c'est-à-dire signifie qu'il y a deux valeurs possibles pour "aucune donnée" : NULL et le vide vide. Dans la plupart des cas, il est redondant d'avoir deux valeurs possibles pour "La convention de Django est d'utiliser la chaîne vide, et non pas la valeur NULL .

Pour les champs basés sur des chaînes de caractères et les champs non basés sur des chaînes de caractères, vous aurez également besoin de définir blank=True si vous souhaitez autoriser les valeurs vides dans les formulaires, comme le site null n'affecte que le stockage dans la base de données (voir blank ).

Nota

Lorsque vous utilisez le backend de la base de données Oracle, la valeur NULL sera stockée pour indiquer la chaîne vide indépendamment de cet attribut.

blank

Field.blank

Si True le champ peut être vide. La valeur par défaut est False .

Notez que ceci est différent de null . null est purement de la base de données, alors que blank est lié à la validation. Si un champ a blank=True la validation du formulaire permettra la saisie d'une valeur vide. Si un champ a blank=False le champ sera obligatoire.

45voto

saran3h Points 1541

Vous avez peut-être votre réponse, mais jusqu'à ce jour, il est difficile de savoir s'il faut mettre null=True ou blank=True ou les deux dans un champ. Je pense personnellement qu'il est inutile et déroutant de fournir autant d'options aux développeurs. Laissez-les gérer les champs nuls ou vides comme ils le souhaitent.

Je suis ce tableau, de Deux boules de Django : enter image description here

Table showing when to use null or blank for each field type

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X