Django CharField vs TextField

302

Qual é a diferença entre CharField()e TextField()no Django? A documentação diz que CharField()deve ser usado para cadeias menores e TextField()para cadeias maiores. Ok, mas onde está a linha traçada entre "pequeno" e "grande"? O que está acontecendo sob o capô aqui que torna esse o caso?

Jonathan Gleason
fonte

Respostas:

354

É uma diferença entre os RDBMSs varchar(ou similares) - geralmente são especificados com um comprimento máximo e podem ser mais eficientes em termos de desempenho ou armazenamento - e text(ou similares) tipos - geralmente são limitados apenas por limites de implementação codificados (não um Esquema do banco de dados).

O PostgreSQL 9, especificamente, afirma que "Não há diferença de desempenho entre esses três tipos" , mas no AFAIK existem algumas diferenças, por exemplo, no MySQL, então isso é algo a ser lembrado.

Uma boa regra é que você use CharFieldquando precisar limitar o comprimento máximo, TextFieldcaso contrário.

Isso também não é realmente específico do Django.

Cat Plus Plus
fonte
43
Por outro lado, se você usa o CharField, deve ter um comprimento máximo
Sam Svenbjorgchristiensensen
17
Descobri que o uso TextFieldpor padrão pode afetar a portabilidade do seu aplicativo. Pode não haver um impacto no desempenho no Postgres, mas o Oracle o armazenará como algo CLOBque tem alguns aborrecimentos, como não poder usar o campo nas instruções WHERE. Apenas algo a considerar.
Rob
3
Deve-se considerar também que no Oracle CharFieldnão pode ter max_lengthmais que 2000 ou emite um ORA-00910: specified length too long for its datatypeerro.
Dinei
É útil observar que, ao considerar os atributos do campo, os documentos do Postgres também dizem (ênfase minha): "a maior cadeia de caracteres possível que pode ser armazenada é de cerca de 1 GB. (O valor máximo permitido para n na declaração do tipo de dados é menor que isso [...] Se você deseja armazenar seqüências longas sem limite superior específico, use texto ou caractere variando sem um especificador de comprimento, em vez de criar um limite arbitrário de comprimento .) "
iff_ou
3
Acredito que a diferença realmente importante entre os dois no django é como uma visão lidará com o campo. Em uma visualização de edição genérica, o TextField será renderizado como uma entrada redimensionável de várias linhas; enquanto o CharField é uma entrada de linha única. Eu não olhei a fonte do django para o TextField, mas assumirei que, se algum html gerado estiver anexado a um TextField, provavelmente implementará uma maneira de manipular adequadamente o texto multilinha.
Mitchell Paredes
36

Em alguns casos, está vinculado à forma como o campo é usado. Em alguns mecanismos de banco de dados, as diferenças de campo determinam como (e se) você procura texto no campo. Os CharFields geralmente são usados ​​para itens pesquisáveis, como se você deseja procurar "um" na sequência "um mais dois". Como as seqüências de caracteres são mais curtas, elas consomem menos tempo para o mecanismo pesquisar. Os TextFields normalmente não devem ser pesquisados ​​(como talvez o corpo de um blog), mas devem conter grandes quantidades de texto. Agora, a maior parte disso depende do DB Engine e, como no Postgres, isso não importa.

Mesmo que isso não importe, se você usa ModelForms, obtém um tipo diferente de campo de edição no formulário. O ModelForm irá gerar um formulário HTML do tamanho de uma linha de texto para um CharField e multilinha para um TextField.

renderbox
fonte
2
Essa é de longe a melhor explicação, pois menciona como gera o campo em um formulário. O Charfield será apenas uma entrada de uma linha, mas o TextField será uma multilinha redimensionável. O TextField faz sentido quando você implementa principalmente visualizações de classe genéricas. Funciona muito bem para um campo de descrição ou algo semelhante. Também gosto de como o renderbox mencionou que você não gostaria de usá-lo para nenhum filtro / pesquisa.
Mitchell Paredes
8

Por exemplo,. 2 campos são adicionados em um modelo como abaixo.

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

Abaixo estão as consultas mysql executadas quando as migrações são aplicadas.


para TextField(descrição) o campo é definido como umlongtext

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

O tamanho máximo TextFielddo MySQL é de 4 GB, de acordo com a visão geral do tipo string .


para CharField(title) o max_length (obrigatório) é definido comovarchar(64)

ALTER TABLE `sometable_sometable` ADD COLUMN `title` varchar(64) NULL;
ALTER TABLE `sometable_sometable` ALTER COLUMN `title` DROP DEFAULT;
Super Nova
fonte
1
nit: os documentos do Django recomendam Avoid using null on string-based fields such as CharField and TextField:: docs.djangoproject.com/en/2.0/ref/models/fields/#null, portanto é melhor mantê-lo null=False.
Modulitos 15/01/19
7

CharFieldtem max_length de 255caracteres enquanto TextFieldpode conter mais que 255caracteres. Use TextFieldquando você tiver uma string grande como entrada. É bom saber que quando o max_lengthparâmetro é passado para um TextFieldpassa a validação de comprimento para o TextAreawidget.

Njeru Cyrus
fonte
"Todos os campos armazenados com VARCHARtipos de coluna têm seu max_lengthlimite restrito a 255 caracteres se você estiver usando unique = True para o campo. " (Ênfase meu.)
l0b0
-4

Eu tive um problema estranho e entendi uma diferença estranha desagradável: quando recebo um URL do usuário como um CharField e o uso em html uma tag por href, ele adiciona esse URL ao meu URL e não é isso que eu quero. Mas quando eu faço isso pelo Textfield, ele passa apenas a URL que o usuário digitou. veja estes: endereço do meu site:http://myweb.com

Entrada do CharField: http://some-address.com

ao clicar nele: http://myweb.comhttp://some-address.com

Entrada do TextField: http://some-address.com

ao clicar nele: http://some-address.com

Devo mencionar que a URL é salva exatamente da mesma forma no DB de duas maneiras, mas não sei por que o resultado é diferente ao clicar nelas.

amin_mirr
fonte