différencier null = True, vide = True dans Django

904

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 se fait avec ForeignKey, DecimalFieldetc. Quelle est la différence fondamentale

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

en ce qui concerne différents ( CharField, ForeignKey, ManyToManyField, DateTimeFieldchamps). Quels sont les avantages / inconvénients de l'utilisation de 1/2/3?

user993563
la source
8
Vous avez de belles réponses à ce sujet ici: stackoverflow.com/questions/8159310/… et ici: stackoverflow.com/questions/4384098/…
juliomalegria
2
Bonne lecture: b-list.org/weblog/2006/jun/28/…
Salman von Abbas
Oui, j'ai aussi ce cas d'utilisation ForeignKeyavec blank=True, mais sans null=True. Lorsque le modèle est enregistré, je souhaite le "publier" automatiquement en créant une entrée publiée à partir de celui-ci. Je ne peux donc pas enregistrer nulldans la base de données, car chaque modèle doit être "publié", mais je veux pouvoir laisser le champ vide dans admin.
osa
Je pense que vous pourriez être intéressé par [Enregistrer les CharField vides et nullables comme null plutôt que comme une chaîne vide] ( code.djangoproject.com/ticket/4136 ). Il existe de nombreuses discussions à ce sujet et un problème très pratique que vous pouvez rencontrer (par exemple, vous voulez ajouter une URL openid pour chaque utilisateur qui peut être nulle et doit être unique).
ramwin

Réponses:

1084

null=Truedéfinit NULL(versus NOT NULL) sur la colonne de votre base de données. Les valeurs vides pour les types de champs Django tels que DateTimeFieldou ForeignKeyseront stockées comme NULLdans la base de données.

blankdétermine si le champ sera requis dans les formulaires. Cela inclut l'administrateur et vos formulaires personnalisés. Si blank=Truealors le champ ne sera pas requis, alors que si c'est Falsele champ ne peut pas être vide.

La combinaison des deux est si fréquente car, généralement, si vous autorisez un champ à être vide dans votre formulaire, vous aurez également besoin de votre base de données pour autoriser les NULLvaleurs de ce champ. L'exception est CharFields et TextFields, qui dans Django ne sont jamais enregistrés sous NULL. Les valeurs vides sont stockées dans la base de données sous forme de 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, ces deux options n'ont pas de sens logique à utiliser (bien qu'il puisse y avoir un cas d'utilisation null=True, blank=Falsesi vous souhaitez qu'un champ soit toujours requis dans les formulaires, facultatif lorsque vous traitez un objet via 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

CHARet les TEXTtypes ne sont jamais enregistrés comme NULLpar Django, c'est donc null=Trueinutile. Cependant, vous pouvez définir manuellement l'un de ces champs Nonepour forcer sa définition en tant que NULL. Si vous avez un scénario où cela pourrait être nécessaire, vous devez toujours l'inclure null=True.

Chris Pratt
la source
8
IntegrityErrors'affiche lorsque Django tente de sauvegarder l'enregistrement dans la base de données. Le champ ne doit pas être rempli par l'utilisateur, et c'est le problème car au niveau de la base de données, il n'est pas nul.
Chris Pratt
5
Non, Chris essaie de montrer pourquoi avoir blank = True sans avoir null = True causerait des problèmes dans un DateTimeField.
Vinod Kurup
4
NOTE aux utilisateurs d'Oracle: Il n'est pas vrai que " CHARet ne TEXTsoient JAMAIS enregistrés comme NULLpar Django". C'est vrai pour la plupart des backends, mais Oracle forcera une chaîne vide à NULL, donc le backend Django Oracle est une exception à la déclaration ci-dessus Django Docs
stv
10
@ChrisPratt Correction mineure de votre message: CharFields peut être enregistré en tant que NULL dans la base de données (traduction Noneen Python) si vous définissez null = True. Les documents disent même d'éviter de définir null = True car cela autorise deux types différents de valeurs "vierges". Je viens de tester ce comportement avec Django 1.8 / MySQL 5.6
Edward D'Souza
3
est que personne ne va parler de la combinaison de: blank=True, null=False, default="something"?
Brian H.
125

C'est ainsi que les cartes blanket nullchamps ORM 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 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 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
)
utilisateur
la source
41
En d'autres termes, blankn'a aucun effet sur la base de données et nullcontrôle si la colonne de base de données autorise les NULLvaleurs. Cette réponse est un très long chemin pour le dire et ne fournit aucune information utile à ce sujet blank.
Carl Meyer
19
@CarlMeyer: Je voulais voir comment cela serait mappé à la base de données et partagé car cela ferait gagner du temps aux autres pour faire de même. Théorie vs exemple font la différence lorsqu'il s'agit d'assimiler et de s'engager dans la mémoire. En fait, j'ai fait l'impossible pour ajouter le mappage d'une base de données que je n'utilisais pas. Merci pour le downvote. Le nombre de personnes qui ont trouvé cela utile n'est manifestement pas d'accord avec vous.
utilisateur
5
Cela pourrait être une réponse utile si vous tiriez des conclusions sommaires des données présentées, mais je ne pense pas que la présentation d'un vidage de données brutes soit une réponse utile. Dans ce cas, il s'agit en fait d'une réponse trompeuse, car (sans autre commentaire), cela implique que l'effet des deux blanket nulldoit être reflété dans les colonnes de la base de données, alors qu'en fait il blankn'affecte que la gestion Python, pas les colonnes de la base de données. D'autres sont libres de voter s'ils le jugent utile; il est également possible pour les personnes induites en erreur par une réponse trompeuse de penser qu'elle était utile.
Carl Meyer
4
La réponse acceptée qui a presque 3 ans explique tout en détail. Il est inutile de répéter les mêmes informations ici.
utilisateur
47

Comme indiqué dans la référence du champ du modèle Django: 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 des valeurs vides comme NULLdans la base de données. La valeur par défaut est False.

Évitez d'utiliser nullsur des champs basés sur des chaînes tels que CharFieldet TextFieldparce que les valeurs de chaîne vides seront toujours stockées en tant que chaînes vides, pas en tant que NULL. Si un champ basé sur une chaîne a null=True, cela signifie qu'il a deux valeurs possibles pour "pas de données": NULLet la chaîne vide. Dans la plupart des cas, il est redondant d'avoir deux valeurs possibles pour «aucune donnée»; la convention de Django est d'utiliser la chaîne vide, non NULL.

Pour les champs basés sur des chaînes et non basés sur des chaînes, vous devrez également définir blank=Truesi vous souhaitez autoriser les valeurs vides dans les formulaires, car le nullparamètre affecte uniquement le stockage de la base de données (voir blank).

Remarque

Lors de l'utilisation du backend de base de données Oracle, la valeur NULL sera stockée pour indiquer la chaîne vide quel que soit cet attribut


blank

Field.blank

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

Notez que ceci est différent de null. nullest purement lié à la base de données, alors qu'il blankest 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.

DiogoLR
la source
46

Il est essentiel de comprendre que les options d'une définition de champ de modèle Django servent (au moins) à deux fins: définir les tables de base de données, définir le format par défaut et valider les formulaires de modèle. (Je dis «par défaut» parce que les valeurs peuvent toujours être remplacées en fournissant un formulaire personnalisé.) Certaines options affectent la base de données, certaines options affectent les formulaires et certaines affectent les deux.

En ce qui concerne nullet blank, d'autres réponses ont déjà précisé que la première affecte la définition de la table de base de données et la seconde affecte la validation du modèle. Je pense que la distinction peut être 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 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, ce n'est pas la méthode recommandée pour rendre les champs basés sur des chaînes facultatifs.)

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

    • L'utilisation la plus courante concerne les champs facultatifs basés sur des chaînes. Comme indiqué dans la documentation , l'idiome Django consiste à utiliser la chaîne vide pour indiquer une valeur manquante. Si NULLétait également autorisé, 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 save()méthode, par exemple). Vous ne voulez pas que l'utilisateur fournisse la valeur dans un formulaire (d'où blank=True), mais vous voulez que la base de données impose qu'une valeur soit toujours fournie ( null=False).

    • Une autre utilisation consiste à indiquer que a ManyToManyFieldest facultatif. Parce que ce champ est implémenté comme une table distincte plutôt que comme une colonne de base de données, nulln'a pas de sens . La valeur de blankaffectera toujours les formulaires, cependant, contrôlant si la validation réussira ou non en l'absence de relations.

  • null=True, blank=False: Cela signifie que le formulaire nécessite une valeur mais pas la base de données. Il s'agit peut-être de la configuration la moins fréquemment utilisée, mais il existe certains cas d'utilisation:

    • Il est parfaitement raisonnable d'exiger que vos utilisateurs incluent toujours une valeur même si elle n'est pas réellement requise par votre logique métier. Après tout, les formulaires ne sont qu'un moyen d'ajouter et de modifier des données. Vous pouvez avoir du code qui génère des données qui n'ont pas besoin de la même validation stricte que celle que vous souhaitez exiger d'un éditeur humain.

    • Un autre cas d'utilisation que j'ai vu est lorsque vous en avez un ForeignKeypour lequel vous ne souhaitez pas autoriser la suppression en cascade . C'est-à-dire qu'en utilisation normale, la relation devrait toujours être là ( blank=False), mais si la chose qu'elle pointe se trouve être supprimée, vous ne voulez pas que cet objet soit également supprimé. Dans ce cas, vous pouvez utiliser null=Trueet on_delete=models.SET_NULLimplémenter un type simple de suppression logicielle .

Kevin Christopher Henry
la source
1
C'est une réponse parfaite, toutes les combinaisons possibles sont expliquées de manière très concise!
RusI
1
Doit être la réponse acceptée.
Tom Mac
28

Vous pouvez cependant avoir votre réponse jusqu'à ce jour, il est difficile de juger s'il faut mettre null = True ou blank = True ou les deux dans un champ. Personnellement, je pense qu'il est assez inutile et déroutant de fournir autant d'options aux développeurs. Laissez le gérer les valeurs nulles ou vides comme bon leur semble.

Je suis ce tableau, de Two Scoops of Django :entrez la description de l'image ici

Tableau indiquant quand utiliser null ou vide pour chaque type de champ

saran3h
la source
26

Simplement null=True base de données doit accepter les NULLvaleurs, d'autre part blank=Truedéfinit lors de la validation du formulaire ce champ doit accepter les valeurs vides ou non (s'il blank=Trueaccepte le formulaire sans valeur dans ce champ et blank=False[valeur par défaut] lors de la validation du formulaire, il affichera ce champ est une erreur obligatoire .

null=True/False lié à la base de données

blank=True/False liés à la validation des formulaires

Ranju R
la source
11

Voici un exemple du champ avec blank= Trueetnull=True

description = models.TextField (vide = True, null = True)

Dans ce cas:: blank = Trueindique à notre formulaire qu'il est autorisé de laisser le champ de description vide

et

null = True: indique à notre base de données qu'il est correct d'enregistrer une valeur nulle dans notre champ db et de ne pas donner d'erreur.

Stryker
la source
7
null = True

Signifie qu'il n'y a aucune contrainte de base de données pour le champ à remplir, vous pouvez donc avoir un objet avec une valeur nulle pour le rempli qui a cette option.

blank = True

Signifie qu'il n'y a pas de contrainte de validation dans les formulaires django. donc lorsque vous remplissez un modelFormpour ce modèle, vous pouvez laisser le champ avec cette option vide.

Milad Khodabandehloo
la source
7

Voici la principale différence de null=Trueet blank=True:

La valeur par défaut des deux nullet blankest False. Ces deux valeurs fonctionnent au niveau du champ, c'est-à-dire si nous voulons conserver un champ nullou blank.

null=Truedéfinira la valeur du champ sur NULLie, aucune donnée. Il s'agit essentiellement de la valeur de la colonne des bases de données.

date = models.DateTimeField(null=True)

blank=Truedétermine si le champ sera requis dans les formulaires. Cela inclut l'administrateur et vos propres formulaires personnalisés.

title = models.CharField(blank=True) // title can be kept blank. Dans la base de données ("")sera stockée. null=True blank=TrueCela signifie que le champ est facultatif en toutes circonstances.

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
la source
6

Les valeurs par défaut null et blank sont False.

Null: il est lié à la base de données. Définit si une colonne de base de données donnée accepte ou non des valeurs nulles.

Vide: il est lié à la validation. Il sera utilisé lors de la validation des formulaires, lors de l'appel de form.is_valid ().

Cela étant dit, il est parfaitement correct d'avoir un champ avec null = True et vide = False. Signification au niveau de la base de données, le champ peut être NULL, mais au niveau de l'application, il s'agit d'un champ obligatoire.

Maintenant, là où la plupart des développeurs se trompent: Définir null = True pour les champs basés sur des chaînes tels que CharField et TextField. Évitez de faire ça. Sinon, vous finirez par avoir deux valeurs possibles pour «aucune donnée», c'est-à-dire: Aucune et une chaîne vide. Avoir deux valeurs possibles pour «aucune donnée» est redondant. La convention Django consiste à utiliser la chaîne vide, pas NULL.

sharif_42
la source
5

Lorsque nous enregistrons quoi que ce soit dans l'administrateur Django, la validation en deux étapes se produit, au niveau de Django et au niveau de la base de données. Nous ne pouvons pas enregistrer de texte dans un champ numérique.

La base de données a le type de données NULL, ce n'est rien. Lorsque Django crée des colonnes dans la base de données, il spécifie qu'elles ne peuvent pas être vides. Et si vous essayez d'enregistrer NULL, vous obtiendrez l'erreur de base de données.

Toujours au niveau de Django-Admin, tous les champs sont obligatoires par défaut, vous ne pouvez pas enregistrer le champ vide, Django vous enverra une erreur.

Donc, si vous souhaitez enregistrer un champ vide, vous devez l'autoriser au niveau de Django et de la base de données. blank = True - autorisera le champ vide dans le panneau d'administration null = True - permettra d'enregistrer NULL dans la colonne de base de données.

Yuriy Kots
la source
5

Il y a un point où null=Truecela serait nécessaire même sur un CharFieldou TextFieldet c'est quand la base de données a leunique drapeau défini pour la colonne.

En d'autres termes, si vous avez un Char / TextField unique dans Django, vous devrez utiliser ceci:

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

Pour CharField ou TextField non unique, vous feriez mieux de sauter le null=Truesinon certains champs seront définis comme NULL tandis que d'autres comme "", et vous devrez vérifier la valeur du champ pour NULL à chaque fois.

Nitin Nain
la source
3

null est pour la base de données et vide est pour la validation des champs que vous souhaitez afficher sur l'interface utilisateur comme textfield pour obtenir le nom de famille de la personne. Si lastname = models.charfield (blank = true), il n'a pas demandé à l'utilisateur d'entrer le nom de famille car c'est le champ optionnel maintenant. Si lastname = models.charfield (null = true), cela signifie que si ce champ n'obtient aucune valeur de l'utilisateur, il sera stocké dans la base de données sous la forme d'une chaîne vide "".

Tabish
la source
1

La signification de null = True et blank = True dans le modèle dépend également de la façon dont ces champs ont été définis dans la classe de formulaire.

Supposons que vous ayez défini la classe suivante:

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

Si la classe de formulaire a été définie comme ceci:

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

Ensuite, le champ «nom» ne sera pas obligatoire (en raison du blanc = vrai dans le modèle) et le champ «adresse» sera obligatoire (en raison du blanc = faux dans le modèle).

Cependant, si la classe ClientForm a été définie comme ceci:

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

Ensuite, les deux champs ('nom' et 'adresse') seront obligatoires, "puisque les champs définis de manière déclarative sont laissés tels quels " ( https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ ) , c'est-à-dire que la valeur par défaut pour l'attribut 'required' du champ de formulaire est True et cela nécessitera que les champs 'name' et 'address' soient remplis, même si, dans le modèle, le champ a été défini sur blank = True.

Carlos Ribeiro
la source
0

Ce tableau ci-dessous illustre les principales différences:

+--------------------------------------------------------------------+
| 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
la source
0

En termes très simples ,

Le blanc est différent de null.

null est purement lié à la base de données , alors que blank est lié à la validation (requis dans le formulaire) .

Si null=True, Django le fera store empty values as NULL in the database. Si un champ l'a blank=True, la validation du formulaire le sera allow entry of an empty value. Si un champ a vide = False, le champ sera obligatoire.

Yash
la source