differentiate null = True, em branco = True no django

904

Quando adicionamos um campo de banco de dados no django, geralmente escrevemos:

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

O mesmo é feito com ForeignKey, DecimalFieldetc. Qual é a diferença básica em ter

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

no que diz respeito a diferentes ( CharField, ForeignKey, ManyToManyField, DateTimeFieldcampos). Quais são as vantagens / desvantagens de usar 1/2/3?

user993563
fonte
8
Você tem boas respostas sobre isso aqui: stackoverflow.com/questions/8159310/… e aqui: stackoverflow.com/questions/4384098/…
juliomalegria
2
Boa leitura: b-list.org/weblog/2006/jun/28/…
Salman von Abbas
Sim, eu também tenho esse caso de uso ForeignKeycom blank=True, mas sem null=True. Quando o modelo é salvo, quero "publicá-lo" automaticamente, criando uma entrada publicada a partir dele. Portanto, não posso salvar nullno banco de dados, pois todos os modelos precisam ser "publicados", mas quero poder deixar o campo vazio no admin.
osa
Acho que você pode estar interessado em [Salvar CharField vazio e anulável como nulo em vez de como uma seqüência vazia] ( code.djangoproject.com/ticket/4136 ). Existem muitas discussões sobre isso e um problema muito prático que você pode encontrar (por exemplo, você deseja adicionar um URL aberto para cada usuário, que pode ser nulo e deve ser único).
ramwin

Respostas:

1083

null=Truedefine NULL(versus NOT NULL) na coluna em seu banco de dados. Valores em branco para tipos de campos do Django, como DateTimeFieldou ForeignKeyserão armazenados como NULLno banco de dados.

blankdetermina se o campo será obrigatório em formulários. Isso inclui o administrador e seus formulários personalizados. Se blank=Trueentão, o campo não será obrigatório, enquanto que se for, Falseo campo não poderá ficar em branco.

A combinação dos dois é tão frequente, porque normalmente, se você deseja que um campo fique em branco em seu formulário, também precisará do seu banco de dados para permitir NULLvalores para esse campo. A exceção é CharFields e TextFields, que no Django nunca são salvos como NULL. Os valores em branco são armazenados no banco de dados como uma sequência vazia ( '').

Alguns exemplos:

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

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

Obviamente, essas duas opções não fazem sentido lógico para usar (embora possa haver um caso de uso, null=True, blank=Falsese você quiser que um campo seja sempre exigido em formulários, opcional ao lidar com um objeto por meio de algo como o shell).

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

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

CHARe TEXTtipos nunca são salvos como NULLno Django, então null=Trueé desnecessário. No entanto, você pode definir manualmente um desses campos Nonepara forçá-lo a defini-lo como NULL. Se você tiver um cenário em que isso seja necessário, você ainda deve incluir null=True.

Chris Pratt
fonte
8
IntegrityErroré gerado quando o Django tenta salvar o registro no banco de dados. O campo não precisa ser preenchido pelo usuário, e esse é o problema, porque no nível do banco de dados não é nulo.
Chris Pratt
5
Não, Chris está tentando apontar por que ter blank = True sem ter null = True causaria problemas em um DateTimeField.
Vinod Kurup
4
NOTA para usuários do Oracle: Não é verdade que " CHARe TEXTNUNCA são salvos como NULLpelo Django". É verdade para a maioria dos backends, mas a Oracle irá forçar uma seqüência vazia para NULL, então o back-end Django Oracle é uma exceção à declaração acima Django Docs
stv
10
@ChrisPratt Correção menor na sua postagem: CharFields pode ser salvo como NULL no banco de dados (traduzido para NonePython) se você definir null = True. Os documentos dizem até para evitar definir null = True, pois permite dois tipos diferentes de valores "em branco". Eu só testei este comportamento com Django 1.8 / MySQL 5.6
Edward D'Souza
3
é ninguém vai mencionar a combinação de: blank=True, null=False, default="something"?
Brian H.
125

É assim que o ORM mapeia blanke nullcampos para o 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)        

Os campos do banco de dados criados para o PostgreSQL 9.4 são:

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

Os campos do banco de dados criados para o MySQL 5.6 são:

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
)
do utilizador
fonte
41
Em outras palavras, blanknão tem efeito no banco de dados e nullcontrola se a coluna do banco de dados permite NULLvalores. Esta resposta é realmente uma maneira longa de dizer isso e não fornece nenhuma informação útil sobre blank.
Carl Meyer
19
@CarlMeyer: Eu queria ver como ele seria mapeado para o banco de dados e compartilhado, pois economizaria tempo para que outras pessoas fizessem o mesmo. Teoria vs exemplo fazem a diferença quando se trata de assimilar e comprometer a memória. Na verdade, fiz o possível para adicionar o mapeamento para um banco de dados que não estava usando. Obrigado pelo voto negativo. O número de pessoas que acharam isso útil obviamente discorda de você.
usuário
5
Pode ser uma resposta útil se você tirar algumas conclusões resumidas dos dados apresentados, mas não acho que apresentar um despejo de dados brutos seja uma resposta útil. Nesse caso, é realmente uma resposta enganosa, pois (sem mais comentários) implica que o efeito de ambos blanke nulldeve ser refletido nas colunas do banco de dados, quando na verdade blankafeta apenas o manuseio do Python, não as colunas do banco de dados. Outros são livres de votar se acharem útil; também é possível que as pessoas que são enganadas por uma resposta enganosa pensem que foi útil.
Carl Meyer
4
A resposta aceita, com quase 3 anos, explica tudo em detalhes. Não faz sentido repetir a mesma informação aqui.
usuário
47

Como dito na referência do Django Model Field: Link

Opções de campo

Os seguintes argumentos estão disponíveis para todos os tipos de campo. Todos são opcionais.


null

Field.null

Se True, o Django armazenará valores vazios como NULLno banco de dados. O padrão é False.

Evite usar nullcampos baseados em cadeias como CharFielde TextFieldporque os valores de cadeias vazias sempre serão armazenados como cadeias vazias, não como NULL. Se um campo baseado em sequência tiver null=True, isso significa que ele tem dois valores possíveis para "sem dados": NULLe a sequência vazia. Na maioria dos casos, é redundante ter dois valores possíveis para "sem dados"; a convenção do Django é usar a string vazia, não NULL.

Para campos baseados em cadeia e não baseados em cadeia, você também precisará definir blank=Truese desejar permitir valores vazios em formulários, pois o nullparâmetro afeta apenas o armazenamento do banco de dados (consulte blank).

Nota

Ao usar o back-end do banco de dados Oracle, o valor NULL será armazenado para indicar a cadeia vazia, independentemente deste atributo


blank

Field.blank

Se True, o campo pode ficar em branco. O padrão é False.

Observe que isso é diferente de null. nullé puramente relacionado ao banco de dados, enquanto que blanké relacionado à validação. Se um campo tiver blank=True, a validação do formulário permitirá a entrada de um valor vazio. Se um campo tiver blank=False, ele será obrigatório.

DiogoLR
fonte
46

É crucial entender que as opções em uma definição de campo de modelo do Django servem (pelo menos) a dois propósitos: definir as tabelas do banco de dados e definir o formato padrão e a validação dos formulários do modelo. (Eu digo "padrão" porque os valores sempre podem ser substituídos fornecendo um formulário personalizado.) Algumas opções afetam o banco de dados, algumas opções afetam os formulários e outras afetam os dois.

Quando se trata de nulle blank, outras respostas já deixaram claro que o primeiro afeta a definição da tabela do banco de dados e o segundo afeta a validação do modelo. Penso que a distinção pode ser ainda mais clara observando os casos de uso para todas as quatro configurações possíveis:

  • null=False, blank=False: Esta é a configuração padrão e significa que o valor é necessário em todas as circunstâncias.

  • null=True, blank=True: Isso significa que o campo é opcional em todas as circunstâncias. (Conforme observado abaixo, porém, essa não é a maneira recomendada de tornar opcionais os campos baseados em string.)

  • null=False, blank=True: Isto significa que o formulário não requerem um valor, mas o banco de dados faz. Existem vários casos de uso para isso:

    • O uso mais comum é para campos opcionais baseados em sequência. Conforme observado na documentação , o idioma do Django é usar a string vazia para indicar um valor ausente. Se NULLtambém fosse permitido, você terminaria com duas maneiras diferentes de indicar um valor ausente.

    • Outra situação comum é que você deseja calcular um campo automaticamente com base no valor de outro (no seu save()método, digamos). Você não deseja que o usuário forneça o valor em um formulário (portanto blank=True), mas deseja que o banco de dados imponha que um valor sempre seja fornecido ( null=False).

    • Outro uso é quando você deseja indicar que a ManyToManyFieldé opcional. Como esse campo é implementado como uma tabela separada e não como uma coluna do banco de dados, nullnão faz sentido . O valor de blankainda afetará as formas, porém, controlando se a validação será ou não bem-sucedida quando não houver relações.

  • null=True, blank=False: Significa que o formulário requer um valor, mas o banco de dados não. Essa pode ser a configuração usada com menos frequência, mas existem alguns casos de uso para isso:

    • É perfeitamente razoável exigir que seus usuários sempre incluam um valor, mesmo que não seja realmente exigido pela sua lógica de negócios. Afinal, os formulários são apenas uma maneira de adicionar e editar dados. Você pode ter um código que está gerando dados que não precisa da mesma validação rigorosa que você deseja exigir de um editor humano.

    • Outro caso de uso que eu vi é quando você tem um ForeignKeypara o qual não deseja permitir exclusão em cascata . Ou seja, no uso normal, a relação deve sempre estar lá ( blank=False), mas se o item para o qual ela foi excluída for excluído, você também não deseja que esse objeto seja excluído. Nesse caso, você pode usar null=Truee on_delete=models.SET_NULLimplementar um tipo simples de exclusão suave .

Kevin Christopher Henry
fonte
1
Esta é uma resposta perfeita, todas as combinações possíveis são explicadas de maneira muito concisa!
RusI 23/03
1
Deve ser a resposta aceita.
Tom Mac
28

Você pode ter sua resposta, no entanto, até hoje, é difícil julgar se nulo = Verdadeiro ou em branco = Verdadeiro ou ambos em um campo. Pessoalmente, acho que é bastante inútil e confuso fornecer tantas opções aos desenvolvedores. Deixe o manipular os nulos ou espaços em branco da maneira que eles desejarem.

Sigo esta tabela, de Two Scoops of Django :insira a descrição da imagem aqui

Tabela mostrando quando usar nulo ou em branco para cada tipo de campo

saran3h
fonte
26

Simplesmente null=Truedefine que o banco de dados deve aceitar NULLvalores; por outro lado, blank=Truena validação do formulário, este campo deve aceitar valores em branco ou não (se blank=Trueele aceitar um formulário sem um valor nesse campo e blank=False[valor padrão] na validação do formulário, será exibido Este erro é obrigatório .

null=True/False relacionado ao banco de dados

blank=True/False relacionado à validação de formulário

Ranju R
fonte
11

Aqui está um exemplo do campo com blank= Trueenull=True

description = models.TextField (em branco = True, null = True)

Nesse caso:: blank = Truediz ao nosso formulário que não há problema em deixar o campo de descrição em branco

e

null = True: diz ao nosso banco de dados que não há problema em registrar um valor nulo no nosso campo db e não dar erro.

Stryker
fonte
7
null = True

Significa que não há restrição de banco de dados para o campo a ser preenchido, portanto, você pode ter um objeto com valor nulo para o preenchido que possui essa opção.

blank = True

Significa que não há restrição de validação em formas de django. portanto, ao preencher um modelFormpara este modelo, você pode deixar o campo com essa opção não preenchida.

Milad Khodabandehloo
fonte
7

Aqui está a principal diferença de null=Truee blank=True:

O valor padrão de ambos nulle blanké Falso. Ambos os valores funcionam no nível do campo, ou seja, se queremos manter um campo nullou blank.

null=Trueirá definir o valor do campo como NULLie, sem dados. É basicamente para o valor da coluna de bancos de dados.

date = models.DateTimeField(null=True)

blank=Truedetermina se o campo será obrigatório em formulários. Isso inclui o administrador e seus próprios formulários personalizados.

title = models.CharField(blank=True) // title can be kept blank. No banco de dados ("")serão armazenados. null=True blank=TrueIsso significa que o campo é opcional em todas as circunstâncias.

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
fonte
6

Os valores padrão de null e blank são False.

Nulo: está relacionado ao banco de dados. Define se uma determinada coluna do banco de dados aceitará valores nulos ou não.

Em branco: está relacionado à validação. Ele será usado durante a validação de formulários, ao chamar form.is_valid ().

Dito isto, é perfeitamente bom ter um campo com null = True e em branco = False. Significado no nível do banco de dados, o campo pode ser NULL, mas no nível do aplicativo, é um campo obrigatório.

Agora, onde a maioria dos desenvolvedores erra: Definindo null = True para campos baseados em string, como CharField e TextField. Evite fazer isso. Caso contrário, você terá dois valores possíveis para "sem dados", ou seja: Nenhum e uma sequência vazia. Ter dois valores possíveis para "sem dados" é redundante. A convenção do Django é usar a string vazia, não NULL.

sharif_42
fonte
5

Quando salvamos algo no admin do Django, ocorre a validação de duas etapas, no nível do Django e no banco de dados. Não podemos salvar texto em um campo numérico.

O banco de dados tem o tipo de dados NULL, não é nada. Quando o Django cria colunas no banco de dados, ele especifica que elas não podem estar vazias. E se você tentar salvar NULL, receberá o erro do banco de dados.

Também no nível do Django-Admin, todos os campos são obrigatórios por padrão, você não pode salvar o campo em branco, o Django gera um erro.

Portanto, se você deseja salvar um campo em branco, é necessário permiti-lo no nível do Django e do banco de dados. blank = True - permitirá campo vazio no painel de administração null = True - permitirá salvar NULL na coluna do banco de dados.

Yuriy Kots
fonte
5

Há um ponto em null=Trueque seria necessário mesmo em um CharFieldou TextFielde é quando o banco de dados tem o uniquesinalizador definido para a coluna.

Em outras palavras, se você possui um Char / TextField exclusivo no Django, precisará usar isso:

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

Para CharField ou TextField não exclusivo, é melhor ignorar o null=Truecaso contrário, alguns campos serão definidos como NULL enquanto outros como "", e você precisará verificar o valor do campo para NULL sempre.

Nitin Nain
fonte
3

null é para banco de dados e em branco é para validação de campos que você deseja mostrar na interface do usuário como campo de texto para obter o sobrenome da pessoa. Se lastname = models.charfield (em branco = true), ele não solicitou ao usuário para inserir o sobrenome, pois esse é o campo opcional agora. Se lastname = models.charfield (null = true) , significa que, se esse campo não obtiver nenhum valor do usuário, ele será armazenado no banco de dados como uma string vazia "".

Tabish
fonte
1

O significado de null = True e em branco = True no modelo também depende de como esses campos foram definidos na classe de formulário.

Suponha que você definiu a seguinte classe:

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

Se a classe do formulário tiver sido definida assim:

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

Em seguida, o campo 'nome' não será obrigatório (devido ao espaço em branco = Verdadeiro no modelo) e o campo 'endereço' será obrigatório (devido ao espaço em branco = Falso no modelo).

No entanto, se a classe ClientForm tiver sido definida assim:

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

Então, os dois campos ('nome' e 'endereço') serão obrigatórios " , pois os campos definidos declarativamente são deixados como estão" ( https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ ) , ou seja, o padrão para o atributo 'obrigatório' do campo do formulário é True e isso exigirá que os campos 'name' e 'address' sejam preenchidos, mesmo que, no modelo, o campo tenha sido definido como blank = True.

Carlos Ribeiro
fonte
0

Esta tabela abaixo demonstra as principais diferenças:

+--------------------------------------------------------------------+
| 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
fonte
0

Em palavras muito simples ,

Em branco é diferente de nulo.

null é puramente relacionado ao banco de dados , enquanto o branco é relacionado à validação (obrigatório no formulário) .

Se o null=TrueDjango quiser store empty values as NULL in the database. Se um campo tiver blank=True, a validação do formulário será allow entry of an empty value. Se um campo estiver em branco = False, o campo será obrigatório.

Yash
fonte