bedakan null = True, blank = True dalam Django


904

Ketika kita menambahkan bidang database di Django, kita biasanya menulis:

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

Hal yang sama dilakukan dengan ForeignKey, DecimalFielddll. Apa perbedaan mendasar dalam memiliki

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

dalam hal yang berbeda ( CharField, ForeignKey, ManyToManyField, DateTimeFieldbidang). Apa kelebihan / kekurangan menggunakan 1/2/3?


8
Anda memiliki jawaban yang bagus tentang hal itu di sini: stackoverflow.com/questions/8159310/… dan di sini: stackoverflow.com/questions/4384098/…
juliomalegria


Ya, saya juga memiliki usecase ini ForeignKeydengan blank=True, tetapi tanpa null=True. Ketika model disimpan, saya ingin "mempublikasikan" secara otomatis dengan membuat entri yang diterbitkan dari itu. Jadi saya tidak dapat menyimpan nullke database, karena setiap model harus "dipublikasikan", tetapi saya ingin dapat membiarkan bidang itu kosong di admin.
Osa

Saya pikir Anda mungkin tertarik dalam [Simpan CharField kosong, nullable sebagai null daripada sebagai string kosong] ( code.djangoproject.com/ticket/4136 ). Ada banyak diskusi tentang ini, dan masalah yang sangat praktis yang mungkin Anda temui (mis. Anda ingin menambahkan url openid untuk setiap pengguna yang bisa nol dan harus unik).
ramwin

Jawaban:


1083

null=Trueset NULL(versus NOT NULL) pada kolom di DB Anda. Nilai kosong untuk tipe bidang Django seperti DateTimeFieldatau ForeignKeyakan disimpan seperti NULLdalam DB.

blankmenentukan apakah bidang akan diminta dalam bentuk. Ini termasuk admin dan formulir khusus Anda. Jika blank=Truemaka bidang tidak akan diperlukan, sedangkan jika Falsebidang itu tidak boleh kosong.

Kombo keduanya begitu sering karena biasanya jika Anda akan membiarkan bidang kosong di formulir Anda, Anda juga akan membutuhkan database Anda untuk memungkinkan NULLnilai untuk bidang itu. Pengecualian adalah CharFields dan TextFields, yang dalam Django tidak pernah disimpan sebagai NULL. Nilai kosong disimpan dalam DB sebagai string kosong ( '').

Beberapa contoh:

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

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

Jelas, kedua opsi itu tidak masuk akal secara logis untuk digunakan (meskipun mungkin ada kasus penggunaan karena null=True, blank=Falsejika Anda ingin bidang selalu diperlukan dalam bentuk, opsional ketika berurusan dengan objek melalui sesuatu seperti shell.)

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

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

CHARdan TEXTtipe tidak pernah disimpan NULLoleh Django, jadi null=Truetidak perlu. Namun, Anda dapat secara manual mengatur salah satu bidang ini Noneuntuk memaksa mengaturnya sebagai NULL. Jika Anda memiliki skenario di mana itu mungkin diperlukan, Anda harus tetap memasukkan null=True.


8
IntegrityErrordinaikkan ketika Django mencoba untuk menyimpan catatan ke database. Field tidak perlu diisi oleh pengguna, dan itu masalahnya karena pada level database itu tidak nol.
Chris Pratt

5
Tidak, Chris mencoba menunjukkan mengapa memiliki blank = True tanpa null = True akan menyebabkan masalah di DateTimeField.
Vinod Kurup

4
CATATAN untuk pengguna Oracle: Tidak benar bahwa " CHARdan TEXTTIDAK PERNAH diselamatkan NULLoleh Django". Memang benar untuk sebagian besar backends, tetapi Oracle akan memaksa string kosong ke NULL, sehingga backend Django Oracle adalah pengecualian untuk pernyataan di atas Django Docs
stv

10
@ChrisPratt Koreksi kecil ke posting Anda: CharFields dapat disimpan sebagai NULL dalam database (diterjemahkan ke Nonedalam Python) jika Anda menetapkan null = True. The docs bahkan mengatakan untuk menghindari pengaturan nol = True karena memungkinkan dua macam nilai-nilai "Blanky". Saya baru saja menguji perilaku ini dengan Django 1.8 / MySQL 5.6
Edward D'Souza

3
adalah tidak ada yang akan menyebutkan kombinasi: blank=True, null=False, default="something"?
Brian H.

125

Ini adalah bagaimana peta blank& nullbidang ORM untuk 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)        

Bidang basis data yang dibuat untuk PostgreSQL 9.4 adalah:

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

Bidang basis data yang dibuat untuk MySQL 5.6 adalah:

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
Dengan kata lain, blanktidak berpengaruh pada database, dan nullmengontrol apakah kolom database memungkinkan NULLnilai. Jawaban ini sangat panjang untuk mengatakan itu, dan tidak memberikan informasi yang berguna tentang blank.
Carl Meyer

19
@CarlMeyer: Saya ingin melihat bagaimana itu akan dipetakan ke database dan dibagikan karena akan menghemat waktu bagi orang lain untuk melakukan hal yang sama. Contoh teori vs membuat perbedaan ketika datang untuk mengasimilasi dan melakukan ke memori. Bahkan, saya berusaha menambahkan pemetaan untuk database yang tidak saya gunakan. Terima kasih untuk downvote. Jumlah orang yang merasakan manfaat ini jelas tidak setuju dengan Anda.
pengguna

5
Ini mungkin jawaban yang berguna jika Anda menarik beberapa kesimpulan ringkasan dari data yang disajikan, tetapi saya tidak berpikir bahwa menyajikan dump data mentah adalah jawaban yang berguna. Dalam hal ini sebenarnya merupakan jawaban yang menyesatkan, karena (tanpa komentar lebih lanjut) itu menyiratkan bahwa efek keduanya blankdan nullharus tercermin dalam kolom database, padahal sebenarnya blankhanya mempengaruhi penanganan Python, bukan kolom basis data. Yang lain bebas untuk memilih jika mereka merasa berguna; itu juga mungkin bagi orang-orang yang disesatkan oleh jawaban yang menyesatkan untuk berpikir itu berguna.
Carl Meyer

4
Jawaban yang diterima yang hampir 3 tahun menjelaskan semuanya secara rinci. Tidak ada gunanya mengulang informasi yang sama di sini.
pengguna

47

Seperti yang dikatakan dalam referensi Bidang Model Django: Tautan

Opsi bidang

Argumen berikut tersedia untuk semua jenis bidang. Semuanya opsional.


null

Field.null

Jika True, Django akan menyimpan nilai kosong seperti NULLdalam database. Defaultnya adalah False.

Hindari penggunaan nullpada bidang berbasis string seperti CharFielddan TextFieldkarena nilai string kosong akan selalu disimpan sebagai string kosong, bukan sebagai NULL. Jika bidang berbasis string memiliki null=True, itu berarti ia memiliki dua nilai yang mungkin untuk "tidak ada data":, NULLdan string kosong. Dalam kebanyakan kasus, itu berlebihan untuk memiliki dua nilai yang mungkin untuk "tidak ada data"; konvensi Django adalah menggunakan string kosong, bukan NULL.

Untuk bidang berbasis string dan non-string, Anda juga perlu mengatur blank=Truejika Anda ingin mengizinkan nilai kosong dalam formulir, karena nullparameter hanya memengaruhi penyimpanan basis data (lihat blank).

Catatan

Saat menggunakan backend database Oracle, nilai NULL akan disimpan untuk menunjukkan string kosong terlepas dari atribut ini


blank

Field.blank

Jika True, bidang tersebut dibiarkan kosong. Defaultnya adalah False.

Perhatikan bahwa ini berbeda dari null. nullmurni terkait dengan basis data, sedangkan blankterkait dengan validasi. Jika suatu bidang memiliki blank=True, validasi formulir akan memungkinkan entri dengan nilai kosong. Jika suatu bidang memiliki blank=False, bidang tersebut akan diperlukan.


46

Sangat penting untuk memahami bahwa opsi dalam definisi bidang model Django melayani (setidaknya) dua tujuan: mendefinisikan tabel database, dan menentukan format default dan validasi formulir model. (Saya katakan "default" karena nilai selalu dapat ditimpa dengan memberikan formulir kustom.) Beberapa opsi mempengaruhi database, beberapa opsi mempengaruhi bentuk, dan beberapa mempengaruhi keduanya.

Ketika datang ke nulldan blank, jawaban lain telah menjelaskan bahwa yang pertama mempengaruhi definisi tabel database dan yang terakhir mempengaruhi validasi model. Saya pikir perbedaan dapat dibuat lebih jelas dengan melihat use case untuk keempat konfigurasi yang mungkin:

  • null=False, blank=False: Ini adalah konfigurasi default dan berarti bahwa nilai diperlukan dalam semua keadaan.

  • null=True, blank=True: Ini berarti bahwa bidang ini opsional dalam semua keadaan. (Seperti yang disebutkan di bawah, meskipun, ini bukan cara yang disarankan untuk membuat bidang berbasis string opsional.)

  • null=False, blank=True: Ini berarti bahwa formulir tidak memerlukan nilai tetapi database tidak. Ada beberapa kasus penggunaan untuk ini:

    • Penggunaan yang paling umum adalah untuk bidang berbasis string opsional. Seperti dicatat dalam dokumentasi , idiom Django adalah menggunakan string kosong untuk menunjukkan nilai yang hilang. Jika NULLjuga diizinkan, Anda akan berakhir dengan dua cara berbeda untuk menunjukkan nilai yang hilang.

    • Situasi umum lainnya adalah Anda ingin menghitung satu bidang secara otomatis berdasarkan nilai yang lain (dalam save()metode Anda , katakanlah). Anda tidak ingin pengguna memberikan nilai dalam bentuk (karenanya blank=True), tetapi Anda ingin agar database menegakkan bahwa nilai selalu diberikan ( null=False).

    • Penggunaan lain adalah ketika Anda ingin menunjukkan bahwa a ManyToManyFieldadalah opsional. Karena bidang ini diimplementasikan sebagai tabel terpisah daripada kolom basis data, nulltidak ada artinya . Nilai blankakan tetap mempengaruhi formulir, meskipun, mengontrol apakah validasi akan berhasil atau tidak ketika tidak ada hubungan.

  • null=True, blank=False: Ini berarti bahwa formulir membutuhkan nilai tetapi database tidak. Ini mungkin konfigurasi yang paling jarang digunakan, tetapi ada beberapa kasus penggunaan untuk itu:

    • Sangat masuk akal untuk mengharuskan pengguna Anda untuk selalu memasukkan nilai bahkan jika itu sebenarnya tidak diperlukan oleh logika bisnis Anda. Bagaimanapun, formulir hanyalah satu cara untuk menambah dan mengedit data. Anda mungkin memiliki kode yang menghasilkan data yang tidak memerlukan validasi ketat yang sama seperti yang Anda inginkan dari editor manusia.

    • Kasus penggunaan lain yang pernah saya lihat adalah ketika Anda memiliki ForeignKeyyang Anda tidak ingin membiarkan penghapusan kaskade . Artinya, dalam penggunaan normal relasi harus selalu ada di sana ( blank=False), tetapi jika hal yang ingin dihapus itu dihapus, Anda tidak ingin objek ini juga dihapus. Jika demikian, Anda dapat menggunakan null=Truedan on_delete=models.SET_NULLmenerapkan penghapusan lunak sederhana .


1
Ini adalah jawaban yang sempurna, semua kemungkinan kombinasi dijelaskan dengan sangat ringkas!
RusI

1
Seharusnya jawaban yang diterima.
Tom Mac

28

Anda mungkin memiliki jawaban Anda sampai hari ini sulit untuk menilai apakah menempatkan null = Benar atau kosong = Benar atau keduanya ke bidang. Saya pribadi berpikir itu sangat tidak berguna dan membingungkan untuk memberikan begitu banyak opsi kepada pengembang. Biarkan pegangan nol atau kosong seperti yang mereka inginkan.

Saya mengikuti tabel ini, dari Two Scoops of Django :masukkan deskripsi gambar di sini

Tabel menunjukkan kapan harus menggunakan nol atau kosong untuk setiap jenis bidang


26

Cukup null=Truemendefinisikan database harus menerima NULLnilai, di sisi lain blank=Truemendefinisikan validasi formulir, bidang ini harus menerima nilai kosong atau tidak (Jika blank=Truemenerima formulir tanpa nilai di bidang itu dan blank=False[nilai default] pada validasi formulir, ini akan menampilkan bidang ini kesalahan yang diperlukan .

null=True/False terkait dengan basis data

blank=True/False terkait dengan validasi formulir


11

Berikut adalah contoh bidang dengan blank= Truedannull=True

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

Dalam hal ini:: blank = Truememberi tahu formulir kami bahwa tidak apa-apa membiarkan bidang deskripsi kosong

dan

null = True: memberi tahu basis data kami bahwa tidak apa-apa untuk merekam nilai nol di bidang db kami dan tidak memberikan kesalahan.


7
null = True

Berarti tidak ada batasan database untuk bidang yang harus diisi, sehingga Anda dapat memiliki objek dengan nilai nol untuk diisi yang memiliki opsi ini.

blank = True

Berarti tidak ada kendala validasi dalam bentuk Django. jadi ketika Anda mengisi modelFormuntuk model ini, Anda dapat meninggalkan bidang dengan opsi ini tidak terisi.


7

Di sini, adalah perbedaan utama null=Truedan blank=True:

Nilai default keduanya nulldan blankFalse. Kedua nilai ini bekerja di level lapangan yaitu, apakah kita ingin menyimpan field nullatau blank.

null=Trueakan menetapkan nilai bidang ke NULLyaitu, tidak ada data. Ini pada dasarnya untuk nilai kolom database.

date = models.DateTimeField(null=True)

blank=Truemenentukan apakah bidang akan diminta dalam bentuk. Ini termasuk admin dan formulir kustom Anda sendiri.

title = models.CharField(blank=True) // title can be kept blank. Dalam database ("")akan disimpan. null=True blank=TrueIni berarti bahwa bidang ini opsional dalam semua keadaan.

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

Nilai default nol dan kosong adalah False.

Null: Ini terkait database. Menentukan apakah kolom basis data yang diberikan akan menerima nilai nol atau tidak.

Kosong: Ini terkait dengan validasi. Ini akan digunakan selama validasi formulir, saat memanggil form.is_valid ().

Yang sedang berkata, itu baik-baik saja untuk memiliki bidang dengan nol = Benar dan kosong = Salah. Berarti pada level database, field tersebut bisa NULL, tetapi pada level aplikasi itu adalah bidang yang wajib diisi.

Sekarang, di mana sebagian besar pengembang salah: Menentukan null = True untuk bidang berbasis string seperti CharField dan TextField. Hindari melakukan itu. Jika tidak, Anda akan memiliki dua kemungkinan nilai untuk "tidak ada data", yaitu: Tidak ada dan string kosong. Memiliki dua nilai yang mungkin untuk "tidak ada data" adalah berlebihan. Konvensi Django adalah menggunakan string kosong, bukan NULL.


5

Ketika kami menyimpan apa pun di admin Django, dua langkah validasi terjadi, pada level Django dan pada tingkat Database. Kami tidak dapat menyimpan teks dalam bidang angka.

Basis data memiliki tipe data NULL, bukan apa-apa. Ketika Django membuat kolom dalam database itu menentukan bahwa mereka tidak boleh kosong. Dan jika Anda akan mencoba untuk menyimpan NULL Anda akan mendapatkan kesalahan basis data.

Juga pada tingkat Django-Admin, semua bidang wajib diisi secara default, Anda tidak dapat menyimpan bidang kosong, Django akan membuat Anda mengalami kesalahan.

Jadi, jika Anda ingin menyimpan bidang kosong Anda harus mengizinkannya pada tingkat Django dan Database. blank = True - akan mengizinkan bidang kosong di panel admin null = True - akan memungkinkan penyimpanan NULL ke kolom database.


5

Ada satu titik di mana null=Trueakan diperlukan bahkan pada CharFieldatau TextFielddan saat itulah database memilikiunique menetapkan bendera untuk kolom.

Dengan kata lain, jika Anda memiliki Char / TextField unik di Django, Anda harus menggunakan ini:

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

Untuk CharField atau TextField yang tidak unik, Anda akan lebih baik melewatkan bagian-bagian null=Truelain yang akan ditetapkan sebagai NULL sementara yang lain sebagai "", dan Anda harus memeriksa nilai bidang untuk NULL setiap kali.


3

null untuk database dan kosong untuk validasi bidang yang ingin Anda tampilkan di antarmuka pengguna seperti bidang teks untuk mendapatkan nama belakang orang. Jika nama belakang = models.charfield (blank = true) itu tidak meminta pengguna untuk memasukkan nama belakang karena ini adalah bidang opsional sekarang. Jika nama belakang = models.charfield (null = true) maka itu berarti jika bidang ini tidak mendapatkan nilai dari pengguna maka itu akan disimpan dalam database sebagai string kosong "".


1

Arti dari null = True dan blank = True dalam model juga tergantung pada bagaimana bidang-bidang ini didefinisikan dalam kelas bentuk.

Misalkan Anda telah mendefinisikan kelas berikut:

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

Jika kelas bentuk telah didefinisikan seperti ini:

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

Kemudian, bidang 'nama' tidak akan wajib (karena kosong = Benar dalam model) dan bidang 'alamat' akan wajib (karena kosong = Salah dalam model).

Namun, jika kelas ClientForm telah didefinisikan seperti ini:

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

Kemudian, kedua bidang ('nama' dan 'alamat') akan wajib, "karena bidang yang didefinisikan secara deklaratif dibiarkan apa adanya" ( https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ ) , yaitu standar untuk atribut 'wajib' dari bidang formulir adalah Benar dan ini akan mengharuskan bidang 'nama' dan 'alamat' diisi, bahkan jika, dalam model, bidang telah disetel ke kosong = Benar.



0

Tabel di bawah ini menunjukkan perbedaan utama:

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

Dengan kata-kata yang sangat sederhana ,

Kosong berbeda dari nol.

nol adalah murni database yang terkait , sedangkan kosong adalah validasi terkait (diperlukan dalam bentuk) .

Jika null=True, Django akan melakukannya store empty values as NULL in the database. Jika suatu bidang memiliki blank=True, validasi formulir akan allow entry of an empty value. Jika bidang kosong = Salah, bidang wajib diisi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.