Django CharField vs TextField

302

¿Cuál es la diferencia entre CharField()y TextField()en Django? La documentación dice que CharField()debe usarse para cadenas más pequeñas y TextField()debe usarse para cadenas más grandes. De acuerdo, pero ¿dónde se dibuja la línea entre "pequeño" y "grande"? ¿Qué está pasando debajo del capó aquí que hace que este sea el caso?

Jonathan Gleason
fuente

Respuestas:

354

Es una diferencia entre los RDBMS varchar(o similares), que generalmente se especifican con una longitud máxima, y ​​podrían ser más eficientes en términos de rendimiento o almacenamiento, y text(o similares) tipos, que generalmente están limitados solo por los límites de implementación codificados (no un Esquema de base de datos).

PostgreSQL 9, específicamente, afirma que "No hay diferencia de rendimiento entre estos tres tipos" , pero AFAIK hay algunas diferencias en, por ejemplo, MySQL, por lo que es algo a tener en cuenta.

Una buena regla general es que la use CharFieldcuando necesite limitar la longitud máxima, de lo TextFieldcontrario.

Esto tampoco es realmente específico de Django.

Cat Plus Plus
fuente
43
Y a la inversa, si usa CharField, entonces debe tener una longitud máxima
Sam Svenbjorgchristiensensen
17
Descubrí que el uso TextFieldpredeterminado puede afectar la portabilidad de su aplicación. Es posible que no haya un impacto en el rendimiento en Postgres, pero Oracle lo almacenará como algo CLOBque tiene algunas molestias, como no poder usar el campo en las declaraciones WHERE. Solo algo a considerar.
Rob
3
También se debe considerar que en Oracle CharFieldno puede tener max_lengthmás de 2000, o emite un ORA-00910: specified length too long for its datatypeerror.
Dinei
Es útil tener en cuenta, al considerar los atributos de campo, que los documentos de Postgres también dicen (énfasis mío): "la cadena de caracteres más larga posible que se puede almacenar es de aproximadamente 1 GB. (El valor máximo que se permitirá para n en la declaración de tipo de datos es menor que eso [...] Si desea almacenar cadenas largas sin límite superior específico, use texto o caracteres que varíen sin un especificador de longitud, en lugar de crear un límite de longitud arbitrario ). "
iff_o
3
Creo que la diferencia realmente importante entre los dos en django es cómo una vista manejará el campo. En una vista de edición genérica, TextField se representará como una entrada redimensionable de varias líneas; mientras que el CharField es una entrada de línea única. No he mirado la fuente de django para TextField, pero voy a suponer que si algún html generado está conectado a un TextField, lo más probable es que implemente una forma de manipular correctamente el texto de varias líneas.
Mitchell Walls
36

En algunos casos está vinculado a cómo se usa el campo. En algunos motores de base de datos, las diferencias de campo determinan cómo (y si) busca texto en el campo. Los CharFields se usan generalmente para cosas que se pueden buscar, como si desea buscar "uno" en la cadena "uno más dos". Como las cadenas son más cortas, el motor necesita menos tiempo para buscar. Los campos de texto generalmente no están destinados a ser buscados (como tal vez el cuerpo de un blog) sino que están destinados a contener grandes fragmentos de texto. Ahora, la mayor parte de esto depende del motor DB y, como en Postgres, no importa.

Incluso si no importa, si usa ModelForms obtendrá un tipo diferente de campo de edición en el formulario. ModelForm generará un formulario HTML del tamaño de una línea de texto para un CharField y multilínea para un TextField.

renderbox
fuente
2
Esta es, de lejos, la mejor explicación porque menciona cómo genera el campo en un formulario. El Charfield solo será una entrada de una línea, pero el TextField será un multilínea redimensionable. TextField tiene sentido cuando implementa principalmente vistas de clase genéricas. Funciona muy bien para un campo de descripción o similar. También me gusta cómo mencionó renderbox que no querría usarlo para ningún filtro / búsqueda.
Mitchell Walls
8

Por ejemplo,. Se agregan 2 campos en un modelo como el siguiente.

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

A continuación se muestran las consultas mysql ejecutadas cuando se aplican las migraciones.


para TextField(descripción) el campo se define como unlongtext

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

La longitud máxima TextFieldde MySQL es de 4 GB de acuerdo con la descripción general del tipo de cadena .


para CharField(título) la longitud máxima (requerida) se define comovarchar(64)

ALTER TABLE `sometable_sometable` ADD COLUMN `title` varchar(64) NULL;
ALTER TABLE `sometable_sometable` ALTER COLUMN `title` DROP DEFAULT;
SuperNova
fuente
1
nit: los documentos de Django recomiendan Avoid using null on string-based fields such as CharField and TextField:: docs.djangoproject.com/en/2.0/ref/models/fields/#null, por lo que es mejor mantenerlo null=False.
modulitos
7

CharFieldtiene una longitud máxima de 255caracteres, mientras que TextFieldpuede contener más de 255caracteres. Úselo TextFieldcuando tenga una cadena grande como entrada. Es bueno saber que cuando el max_lengthparámetro se pasa a TextField, pasa la validación de longitud al TextAreawidget.

Njeru Cyrus
fuente
"Todos los campos que se almacenan con VARCHARtipos de columna tienen un max_lengthlímite de 255 caracteres si está usando unique = True para el campo " (Mi énfasis).
l0b0
-4

Tuve un problema extraño y entendí una diferencia extraña desagradable: cuando obtengo una URL del usuario como CharField y luego la uso en html una etiqueta de href, agrega esa url a mi url y eso no es lo que quiero. Pero cuando lo hago por Textfield pasa solo la URL que ingresó el usuario. mira estos: mi dirección del sitio web:http://myweb.com

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

Al hacer clic en él: http://myweb.comhttp://some-address.com

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

Al hacer clic en él: http://some-address.com

Debo mencionar que la URL se guarda exactamente igual en la base de datos de dos maneras, pero no sé por qué el resultado es diferente al hacer clic en ellas

amin_mirr
fuente