differentiate null = Doğru, boş = Django'da doğru


902

Django'ya bir veritabanı alanı eklediğimizde genellikle şunu yazıyoruz:

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

Aynı şey ForeignKey, DecimalFieldvb. İle yapılır . Sahip olmanın temel farkı nedir?

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

Farklı (açısından CharField, ForeignKey, ManyToManyField, DateTimeField) alanlar. 1/2/3 kullanmanın avantajları / dezavantajları nelerdir?




Evet, ben de bu usecase ile ForeignKeybirlikte blank=True, ama olmadan null=True. Model kaydedildiğinde, kendisinden yayınlanmış bir giriş oluşturarak modeli otomatik olarak "yayınlamak" istiyorum. Bu nedenle null, her modelin "yayınlanması" gerektiğinden veritabanına kaydedemiyorum , ancak alanı admin'de boş bırakmak istiyorum.
osa

Ben [boş, boş null edilebilir CharField'ın boş bir dize yerine boş olarak kaydet] ile ilgilenebileceğinizi düşünüyorum ( code.djangoproject.com/ticket/4136 ). Bununla ilgili birçok tartışma var ve karşılaşabileceğiniz çok pratik bir sorun var (örneğin, her kullanıcı için null olabilecek ve benzersiz olması gereken bir openid url eklemek istiyorsunuz).
ramwin

Yanıtlar:


1082

null=TrueDB'nizdeki sütunda ayarlar NULL(karşı NOT NULL). Gibi Django alan türleri için boş değerleri DateTimeFieldveya ForeignKeyolarak saklanacaktır NULLDB.

blankalanın formlarda gerekli olup olmayacağını belirler. Buna yönetici ve özel formlarınız da dahildir. Eğer blank=Trueöyleyse alan gerekli olmayacak, oysa Falsealan boş bırakılamaz.

İkisinin birleşimi çok sıktır, çünkü genellikle bir alanın formunuzda boş olmasına izin verirseniz, NULLo alanın değerlerine izin vermek için veritabanınıza da ihtiyacınız olacaktır . İstisna, Django'da asla olarak kaydedilmeyen CharFields ve TextFields'dir . Boş değerler DB'de boş bir dize ( ) olarak saklanır .NULL''

Birkaç örnek:

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

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

Açıkçası, Bu iki seçenek kullanmak mantıklı değil (ancak null=True, blank=Falsebir alanın her zaman formlarda gerekli olmasını istiyorsanız, kabuk gibi bir şeyle bir nesne ile uğraşırken isteğe bağlı olabilir).

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

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

CHARve TEXTtipler asla NULLDjango tarafından kaydedilmez , bu yüzden null=Truegereksizdir. Ancak, el için aşağıdaki alanlardan birini ayarlayabilirsiniz Nonekuvvet olarak ayarlamak için NULL. Bunun gerekli olabileceği bir senaryo varsa, yine de eklemeniz gerekir null=True.


8
IntegrityErrorDjango kaydı veritabanına kaydetmeye çalıştığında yükseltilir. Alanın kullanıcı tarafından doldurulması zorunlu değildir ve bu sorun olur çünkü veritabanı düzeyinde boş değildir.
Chris Pratt

5
Hayır, Chris null = True olmadan blank = True'a sahip olmanın neden bir DateTimeField öğesinde sorunlara neden olduğunu göstermeye çalışıyor.
Vinod Kurup

4
Oracle kullanıcıları için NOT: " CHARve Django tarafından TEXTASLA kaydedilmediği " doğru değildir NULL. Çoğu arka uç için doğrudur, ancak Oracle boş bir dizeyi NULL'a zorlayacaktır, bu nedenle Django Oracle arka ucu yukarıdaki ifade Django Docs
stv

10
Yayınınıza @ChrisPratt Minör düzeltme: CharFields olabilir (çevirme veritabanında NULL olarak kaydedilmiş olsun Noneset boş = true ise Python). Dokümanlar bile "blanky" değerler iki farklı türde izin verdiğinden null adlı = true ayarı önlemek için söylüyorlar. Bu davranışı Django 1.8 / MySQL 5.6 ile test ettim
Edward D'Souza

3
kimse kombinasyonu söz gidiyor: blank=True, null=False, default="something"?
Brian H.

124

ORM , Django 1.8 için bu şekilde haritaları blankve nullalanları

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)        

PostgreSQL 9.4 için oluşturulan veritabanı alanları :

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

MySQL 5.6 için oluşturulan veritabanı alanları şunlardır:

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
)

41
Başka bir deyişle, blankveritabanı üzerinde hiçbir etkisi yoktur nullve veritabanı sütununun NULLdeğerlere izin verip vermediğini denetler . Bu cevap, bunu söylemenin çok uzun bir yoludur ve hakkında yararlı bilgiler sağlamaz blank.
Carl Meyer

19
@CarlMeyer: Veritabanına nasıl eşleneceğini görmek istedim ve başkalarının da aynı şeyi yapması için zaman kazandıracağı için paylaştım. Teori ve örnek, belleğe asimile etme ve bağlılık konusunda fark yaratır. Aslında, kullanmadığım bir veritabanı için eşleme eklemek için yolumdan gittim. Downvote için teşekkürler. Bunu yararlı bulan kişi sayısı kesinlikle size katılmıyor.
kullanıcı

5
Sunulan verilerden bazı özet sonuçlar çıkarırsanız yararlı bir cevap olabilir, ancak ham veri dökümü sunmanın yararlı bir cevap olduğunu düşünmüyorum. Her iki etkisi olduğunu ima (daha fazla yorum yapmadan) beri Bu durumda, aslında bir yanıltıcı cevaptır blankve nullaslında zaman, veritabanı sütunlarda yansıtılmalıdır blanksadece Python taşıma değil, veritabanı sütunları etkiler. Diğerleri yararlı bulduklarında oy kullanmakta serbesttirler; yanıltıcı bir cevapla aldatılan insanlar için bunun yararlı olduğunu düşünmek de mümkündür .
Carl Meyer

4
Neredeyse 3 yaşında olan kabul edilen cevap her şeyi ayrıntılı olarak açıklıyor. Burada aynı bilgiyi tekrarlamanın bir anlamı yok.
kullanıcısı

47

Django Model Alanı referansında belirtildiği gibi: Bağlantı

Alan seçenekleri

Aşağıdaki bağımsız değişkenler tüm alan türleri için kullanılabilir. Hepsi isteğe bağlıdır.


null

Field.null

Eğer TrueDjango boş değerleri NULLveritabanında olduğu gibi saklar . Varsayılan değerFalse .

Kullanmaktan kaçının nullgibi dize tabanlı alanlarda CharFieldve TextFieldboş dize değerleri her zaman değil boş dizeleri olarak depolanır çünkü NULL. Dize tabanlı bir alan varsanull=True , "veri yok": NULLve boş dize için iki olası değere sahip olduğu anlamına gelir . Çoğu durumda, "veri yok" için iki olası değere sahip olmak gereksizdir; Django kuralı boş dizeyi kullanmaktır, değil NULL.

Hem dize tabanlı hem de dize tabanlı olmayan alanlar için, parametre yalnızca veritabanı depolamasını etkilediğinden blank=Trueformlarda boş değerlere izin vermek isteyip istemediğinizi de ayarlamanız gerekir null(bkz. blank).

Not

Oracle veritabanı arka ucunu kullanırken, bu özelliğe bakılmaksızın boş dizeyi belirtmek için NULL değeri saklanır


blank

Field.blank

Eğer True , alan boş bırakılabilir. Varsayılan değer False.

Bunun farklı olduğunu unutmayın null. nullyalnızca veritabanı ile ilgilidir, oysa blankdoğrulama ile ilgilidir. Bir alan varsa blank=True, form doğrulaması boş bir değerin girilmesine izin verir. Bir alan varsa alan blank=Falsezorunludur.


46

Bir Django model alan tanımındaki seçeneklerin (en az) iki amaca hizmet ettiğini anlamak çok önemlidir: veritabanı tablolarını tanımlama ve model formlarının varsayılan biçimini ve doğrulamasını tanımlama. ("Varsayılan" diyorum çünkü değerler her zaman özel bir form sağlayarak geçersiz kılınabilir.) Bazı seçenekler veritabanını etkiler, bazı seçenekler formları etkiler ve bazıları her ikisini de etkiler.

O gelince nullve blankeski veritabanı tablosu tanımı etkiler ve ikincisi modeli doğrulama etkilediğini, diğer cevaplar zaten açık hale getirmiştir. Bence bu ayrım, dört olası konfigürasyon için de kullanım durumlarına bakılarak daha da netleştirilebilir:

  • null=False, blank=False: Bu varsayılan yapılandırmadır ve değerin her durumda gerekli olduğu anlamına gelir.

  • null=True, blank=True: Bu, alanın her koşulda isteğe bağlı olduğu anlamına gelir. (Bununla birlikte, aşağıda belirtildiği gibi, dize tabanlı alanları isteğe bağlı yapmanın önerilen yolu bu değildir .)

  • null=False, blank=True: Bu, formun bir değer gerektirmediği, ancak veritabanının gerektirdiği anlamına gelir. Bunun için birkaç kullanım durumu vardır:

    • En yaygın kullanım isteğe bağlı dize tabanlı alanlar içindir. Belgelerde belirtildiği gibi , Django deyimi eksik bir değeri belirtmek için boş dize kullanmaktır. NULLAyrıca izin verildiyse , eksik bir değeri belirtmek için iki farklı yolla karşılaşırsınız.

    • Bir diğer yaygın durum, bir alanı diğerinin değerine göre otomatik olarak hesaplamak istediğinizdir ( save()yönteminizde söyleyin). Kullanıcının değeri bir formda sağlamasını istemezsiniz (dolayısıyla blank=True), veritabanının her zaman bir değerin her zaman sağlandığını ( null=False) sağlamasını istersiniz .

    • Başka bir kullanım, a'nın ManyToManyFieldisteğe bağlı olduğunu belirtmek istediğiniz zamandır. Bu alan bir veritabanı sütunu yerine ayrı bir tablo olarak uygulandığından nullanlamsızdır . Bununla birlikte, değeri blankhala formları etkileyecek, hiçbir ilişki olmadığında validasyonun başarılı olup olmayacağını kontrol edecektir.

  • null=True, blank=False: Bu, formun bir değer gerektirdiği, ancak veritabanının gerektirmediği anlamına gelir. Bu en sık kullanılmayan yapılandırma olabilir, ancak bunun için bazı kullanım durumları vardır:

    • İş mantığınız için gerçekten gerekli olmasa bile kullanıcılarınızdan her zaman bir değer eklemelerini istemek son derece mantıklıdır. Sonuçta, formlar veri eklemenin ve düzenlemenin yalnızca bir yoludur. Bir insan düzenleyicinin gerektirdiği aynı sıkı doğrulamaya ihtiyaç duymayan veri üreten bir kodunuz olabilir.

    • Gördüğüm bir başka kullanım örneği, basamaklı silme işlemineForeignKey izin vermek istemediğiniz bir . Yani, normal kullanımda ilişki her zaman orada olmalıdır ( ), ancak işaret ettiği şey silinirse, bu nesnenin de silinmesini istemezsiniz. Bu durumda , basit bir tür yumuşak silme işlemini kullanabilir ve uygulayabilirsiniz .blank=Falsenull=Trueon_delete=models.SET_NULL


1
Bu mükemmel bir cevaptır, tüm olası kombinasyonlar çok özlü bir şekilde açıklanmıştır!
RusI

1
Kabul edilen cevap olmalı.
Tom Mac

28

Ancak cevabınızı bu güne kadar bir alana null = True veya blank = True veya her ikisini birden koyup koymayacağınıza karar vermek zor olabilir. Kişisel olarak, geliştiricilere bu kadar çok seçenek sunmanın oldukça yararsız ve kafa karıştırıcı olduğunu düşünüyorum. Boşlukları veya boşlukları istedikleri gibi işlemek için bırakın.

Bu tabloyu Django'nun İki Kepçesinden takip ediyorum :resim açıklamasını buraya girin

Her alan türü için ne zaman boş veya boş kullanılacağını gösteren tablo


26

Basitçe null=Trueveritabanı kabul etmelidir tanımlayan NULLdiğer taraftan üzerinde, değerleri blank=Truevarsa bu alan (boş değerleri veya değil kabul etmelidir form doğrulama üzerinde tanımlayıp blank=Trueo bu alanda değer ve olmadan formu kabul blank=Falseo gösterecektir form doğrulama üzerinde [varsayılan değer] Bu alan gereklidir hatası.

null=True/False veritabanı ile ilgili

blank=True/False form doğrulaması ile ilgili


11

İşte alanıyla ilgili bir örnek blank= True venull=True

description = models.TextField (boş = Doğru, null = Doğru)

Bu durumda:: blank = Trueformumuza açıklama alanını boş bırakmanın uygun olduğunu bildirir

ve

null = True: veritabanımıza db alanımızda boş bir değer kaydetmenin ve bir hata vermemenin uygun olduğunu söyler.


7

Burada, temel farklılığı null=Trueve blank=True:

Her iki varsayılan değeri nullve blankFalse. Bu değerlerin her ikisi bir alan tutmak isteyip, saha düzeyinde yani çalışmak nullveya blank.

null=Truealanın değerini NULLyani veri yok olarak ayarlar . Temelde veritabanları sütun değeri içindir.

date = models.DateTimeField(null=True)

blank=Truealanın formlarda gerekli olup olmayacağını belirler. Buna yönetici ve kendi özel formlarınız da dahildir.

title = models.CharField(blank=True) // title can be kept blank. Veritabanında ("")saklanacaktır. null=True blank=TrueBu, alanın her koşulda isteğe bağlı olduğu anlamına gelir.

epic = models.ForeignKey(null=True, blank=True)
// The exception is CharFields() and TextFields(), which in Django are never saved as NULL. Blank values a

6
null = True

Doldurulacak alan için veritabanı kısıtlaması olmadığı anlamına gelir, bu nedenle bu seçeneğe sahip doldurulmuş için boş değerli bir nesneye sahip olabilirsiniz.

blank = True

Django formlarında validasyon kısıtlaması olmadığı anlamına gelir. bu nedenle modelFormbu model için a'yı doldurduğunuzda bu seçeneğin doldurulmadığı alan bırakabilirsiniz.


6

Varsayılan null ve blank değerleri False şeklindedir.

Null: Veri tabanı ile ilgilidir. Belirli bir veritabanı sütununun null değerleri kabul edip etmeyeceğini tanımlar.

Boş: Doğrulama ile ilgilidir. Form doğrulaması sırasında form.is_valid () çağrılırken kullanılır.

Olduğu söyleniyor, null = True ve blank = False olan bir alana sahip olmak gayet iyi. Veritabanı düzeyinde anlam alan NULL olabilir, ancak uygulama düzeyinde zorunlu bir alandır.

Şimdi, çoğu geliştirici yanlış anlıyor: CharField ve TextField gibi dize tabanlı alanlar için null = True tanımlaması. Bunu yapmaktan kaçının. Aksi takdirde, “veri yok” için iki olası değere sahip olursunuz, yani: Yok ve boş bir dize. “Veri yok” için iki olası değere sahip olmak gereksizdir. Django kuralı NULL değil, boş dize kullanmaktır.


5

Django yöneticisine bir şey kaydettiğimizde, Django düzeyinde ve Veritabanı düzeyinde iki adım doğrulaması gerçekleşir. Sayı alanına metin kaydedemiyoruz.

Veritabanında NULL veri türü var, hiçbir şey yok. Django veritabanında sütunlar oluşturduğunda bunların boş olamayacağını belirtir. Ve eğer NULL kaydetmeye çalışacaksanız veritabanı hatası alırsınız.

Ayrıca Django-Yönetici düzeyinde, varsayılan olarak tüm alanlar zorunludur, boş alanı kaydedemezsiniz, Django size bir hata gönderir.

Bu nedenle, boş alanı kaydetmek istiyorsanız, Django ve Veritabanı düzeyinde izin vermeniz gerekir. blank = True - yönetici panelinde boş alana izin verir null = True - veritabanı sütununa NULL kaydedilmesine izin verir.


5

null=TrueBir CharFieldveya üzerinde bile gerekli olabilecek bir nokta vardır TextFieldve bu da veritabanının uniquesütun için ayarlanmış bayrağına sahip olmasıdır .

Başka bir deyişle, Django'da benzersiz bir Char / TextField öğeniz varsa, bunu kullanmanız gerekir:

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

Benzersiz olmayan CharField veya TextField için, atlamadan daha iyi olursunuz, null=Trueaksi takdirde bazı alanlar NULL olarak ayarlanırken diğerleri "" olarak ayarlanır ve her zaman NULL için alan değerini kontrol etmeniz gerekir.


3

null veritabanı içindir ve blank , kişinin soyadını almak için metin alanı gibi kullanıcı arabiriminde göstermek istediğiniz alanların doğrulanması içindir. Eğer lastname = models.charfield (boş = true) Bu isteğe bağlı alan şimdi olduğu gibi o soyadını girmesini rica farlılık. Eğer lastname = models.charfield (boş = true) o zaman bu alan doesnot kullanıcıdan herhangi bir değeri alırsanız o zaman boş bir dize "" olarak veritabanında depolamak anlamına gelir.


1

Modeldeki null = True ve blank = True'un anlamı, bu alanların form sınıfında nasıl tanımlandığına da bağlıdır.

Aşağıdaki sınıfı tanımladığınızı varsayalım:

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

Form sınıfı şu şekilde tanımlandıysa:

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

Daha sonra, 'ad' alanı zorunlu olmayacak (blank = modeldeki True nedeniyle) ve 'adres' alanı zorunlu olacaktır (blank = modeldeki False nedeniyle).

Ancak, ClientForm sınıfı şu şekilde tanımlandıysa:

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

Daha sonra, her iki alanlar ( 'name' ve 'adresi'), zorunlu olacak "bildirimli tanımlanmış alanlar bırakılır beri olduğu gibi" ( https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ ) , yani form alanının 'zorunlu' özniteliği için varsayılan değer True'dur ve bu, modelde alan blank = True olarak ayarlanmış olsa bile 'name' ve 'address' alanlarının doldurulmasını gerektirir.



0

Aşağıdaki tablo ana farklılıkları göstermektedir:

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

0

Çok basit kelimelerle ,

Boş, null değerinden farklıdır.

Boş olan saf veritabanı ile ilgili iken, boş doğrulama ile ilgili (formunda gerekli) bir .

Eğer null=TrueDjango yapacak store empty values as NULL in the database. Bir alan varsa blank=True, form doğrulaması yapılır allow entry of an empty value. Bir alan boş = False ise, alan gerekir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.