Django CharField vs TextField

302

Apa perbedaan antara CharField()dan TextField()di Django? The dokumentasi mengatakan bahwa CharField()harus digunakan untuk string yang lebih kecil dan TextField()harus digunakan untuk string yang lebih besar. Oke, tapi di mana garis yang ditarik antara "kecil" dan "besar"? Apa yang terjadi di bawah tenda di sini yang membuat ini menjadi masalah?

Jonathan Gleason
sumber

Jawaban:

354

Ini perbedaan antara RDBMS varchar(atau serupa) - yang biasanya ditentukan dengan panjang maksimum, dan mungkin lebih efisien dalam hal kinerja atau penyimpanan - dan text(atau serupa) jenis - yang biasanya dibatasi hanya oleh batas implementasi hardcoded (bukan Skema DB).

PostgreSQL 9, secara khusus, menyatakan bahwa "Tidak ada perbedaan kinerja di antara ketiga jenis ini" , tetapi AFAIK ada beberapa perbedaan dalam mis. MySQL, jadi ini adalah sesuatu yang perlu diingat.

Aturan praktis yang baik adalah bahwa Anda menggunakan CharFieldsaat Anda perlu membatasi panjang maksimum, TextFieldjika tidak.

Ini tidak benar-benar spesifik Django, juga.

Cat Plus Plus
sumber
43
Dan sebaliknya, jika Anda menggunakan CharField maka Anda harus memiliki panjang maksimal
Sam Svenbjorgchristiensensen
17
Saya telah menemukan bahwa menggunakan TextFieldsecara default dapat memengaruhi portabilitas aplikasi Anda. Mungkin tidak ada hit kinerja pada Postgres, tetapi Oracle akan menyimpannya sebagai CLOByang memiliki beberapa gangguan, seperti tidak dapat menggunakan bidang dalam pernyataan WHERE. Hanya sesuatu yang perlu dipertimbangkan.
Rob
3
Orang juga harus mempertimbangkan bahwa di Oracle CharFieldtidak boleh max_lengthlebih dari 2000, atau ia mengeluarkan ORA-00910: specified length too long for its datatypekesalahan.
Dinei
Berguna untuk dicatat, ketika mempertimbangkan atribut bidang, dokumen Postgres itu juga mengatakan (penekanan milik saya): "string karakter terpanjang yang dapat disimpan adalah sekitar 1 GB. (Nilai maksimum yang akan diizinkan untuk n dalam deklarasi tipe data adalah kurang dari itu [...] Jika Anda ingin menyimpan string panjang tanpa batas atas spesifik, gunakan teks atau karakter yang bervariasi tanpa
penentu
3
Saya percaya perbedaan yang sangat penting antara keduanya di Django adalah bagaimana pandangan akan menangani lapangan. Dalam tampilan edit umum, TextField akan ditampilkan sebagai input multi-line yang cukup besar; sementara CharField adalah input satu baris. Saya belum melihat sumber Django untuk TextField, tapi saya akan berasumsi jika ada html yang dihasilkan terpasang ke TextField, maka kemungkinan besar akan menerapkan cara untuk memanipulasi teks multline dengan benar.
Mitchell Walls
36

Dalam beberapa kasus ini terkait dengan bagaimana bidang tersebut digunakan. Dalam beberapa mesin DB perbedaan bidang menentukan bagaimana (dan jika) Anda mencari teks di lapangan. CharFields biasanya digunakan untuk hal-hal yang dapat dicari, seperti jika Anda ingin mencari "satu" di string "satu tambah dua". Karena dawai lebih pendek, mereka kurang memakan waktu untuk mesin untuk mencari. TextFields biasanya tidak dimaksudkan untuk dicari (seperti mungkin badan blog) tetapi dimaksudkan untuk menampung potongan teks yang besar. Sekarang sebagian besar tergantung pada DB Engine dan seperti pada Postgres, itu tidak masalah.

Bahkan jika itu tidak masalah, jika Anda menggunakan ModelForms Anda mendapatkan berbagai jenis bidang pengeditan dalam formulir. ModelForm akan menghasilkan bentuk HTML seukuran satu baris teks untuk CharField dan multiline untuk TextField.

renderbox
sumber
2
Sejauh ini, ini adalah penjelasan terbaik karena ini menyebutkan bagaimana ia menghasilkan bidang dalam bentuk. Charfield hanya akan menjadi input satu baris, tetapi TextField akan menjadi multiline yang dapat diubah ukurannya. TextField masuk akal ketika Anda terutama menerapkan pandangan kelas generik. Ini berfungsi baik untuk bidang deskripsi atau sejenisnya. Saya juga suka bagaimana renderbox menyebutkan bahwa Anda tidak ingin menggunakannya untuk filter / pencarian.
Mitchell Walls
8

Untuk mis.,. 2 bidang ditambahkan dalam model seperti di bawah ini ..

description = models.TextField(blank=True, null=True)
title = models.CharField(max_length=64, blank=True, null=True)

Di bawah ini adalah kueri mysql yang dijalankan ketika migrasi diterapkan.


untuk TextField(deskripsi) bidang didefinisikan sebagai alongtext

ALTER TABLE `sometable_sometable` ADD COLUMN `description` longtext NULL;

Panjang maksimum TextFieldMySQL adalah 4GB menurut string-type-overview .


untuk CharField(judul), max_length (wajib) didefinisikan sebagaivarchar(64)

ALTER TABLE `sometable_sometable` ADD COLUMN `title` varchar(64) NULL;
ALTER TABLE `sometable_sometable` ALTER COLUMN `title` DROP DEFAULT;
SuperNova
sumber
1
nit: dokumen Django merekomendasikan Avoid using null on string-based fields such as CharField and TextField:: docs.djangoproject.com/en/2.0/ref/models/fields/#null jadi sebaiknya disimpan null=False.
modulitos
7

CharFieldmemiliki 255karakter max_length sementara TextFielddapat menampung lebih dari 255karakter. Gunakan TextFieldsaat Anda memiliki string besar sebagai input. Adalah baik untuk mengetahui bahwa ketika max_lengthparameter dilewatkan ke dalam TextFielditu melewati validasi panjang ke TextAreawidget.

Njeru Cyrus
sumber
"Setiap bidang yang disimpan dengan VARCHARtipe kolom max_lengthdibatasi hingga 255 karakter jika Anda menggunakan unique = True untuk bidang tersebut. " (Penekanan saya.)
l0b0
-4

Saya punya masalah aneh dan mengerti perbedaan aneh yang tidak menyenangkan: ketika saya mendapatkan URL dari pengguna sebagai CharField dan kemudian menggunakannya dalam html tag oleh href, itu menambahkan url ke url saya dan itu bukan yang saya inginkan. Tetapi ketika saya melakukannya dengan Textfield hanya melewati URL yang dimasukkan pengguna. lihat ini: alamat situs web saya:http://myweb.com

EnterField entery: http://some-address.com

saat mengkliknya: http://myweb.comhttp://some-address.com

Enter TextField: http://some-address.com

saat mengkliknya: http://some-address.com

Saya harus menyebutkan bahwa URL disimpan persis sama dalam DB dengan dua cara tetapi saya tidak tahu mengapa hasilnya berbeda ketika mengkliknya

amin_mirr
sumber