Django CharField vs TextField


302

Jaka jest różnica między CharField()i TextField()w Django? Dokumentacja mówi, że CharField()należy stosować mniejsze strun i TextField()powinny być wykorzystywane do większych łańcuchów. Okej, ale gdzie przebiega granica między „małym” a „dużym”? Co się tu dzieje pod maską, co sprawia, że ​​tak jest?

Odpowiedzi:


354

Jest to różnica między RDBMS varchar(lub podobnymi) - są one zwykle określane z maksymalną długością i mogą być bardziej wydajne pod względem wydajności lub pamięci - i text(lub podobnymi) typami - są one zwykle ograniczone tylko zakodowanymi limitami implementacyjnymi (nie jest to Schemat DB).

PostgreSQL 9 w szczególności stwierdza, że „Nie ma różnicy w wydajności między tymi trzema typami” , ale AFAIK istnieją pewne różnice np. W MySQL, więc należy o tym pamiętać.

Dobrą zasadą jest to, że używasz, CharFieldgdy musisz ograniczyć maksymalną długość, w TextFieldprzeciwnym razie.

To nie jest tak naprawdę specyficzne dla Django.


43
I odwrotnie, jeśli używasz CharField, musisz mieć maksymalną długość
Sam Svenbjorgchristiensensen

17
Odkryłem, że używanie TextFielddomyślnie może mieć wpływ na przenośność Twojej aplikacji. Postgres może nie wpłynąć na wydajność, ale Oracle zapisze go jako taki, CLOBktóry ma pewne irytacje, takie jak niemożność użycia pola w instrukcjach WHERE. Tylko coś do rozważenia.
Rob

3
Należy również wziąć pod uwagę, że w Oracle CharFieldnie może mieć max_lengthwięcej niż 2000 lub powoduje ORA-00910: specified length too long for its datatypebłąd.
Dinei

Warto zauważyć, że rozważając atrybuty pola, również dokumenty Postgresa (podkreślenie moje): „najdłuższy możliwy ciąg znaków, który można zapisać, to około 1 GB. (Maksymalna wartość, która będzie dozwolona dla nw deklaracji typu danych, to mniej niż to [...] Jeśli chcesz przechowywać długie ciągi bez określonego górnego limitu, użyj tekstu lub znaków różniących się bez określenia długości, zamiast tworzyć dowolny limit długości .) "
iff_or

3
Uważam, że naprawdę istotną różnicą między nimi w django jest sposób, w jaki widok poradzi sobie z tym polem. W ogólnym widoku edycji TextField będzie renderowany jako wielowierszowy, zmienny rozmiar danych wejściowych; podczas gdy CharField jest pojedynczym wejściem liniowym. Nie spojrzałem na źródło django dla TextField, ale założę, że jeśli jakikolwiek wygenerowany HTML zostanie dołączony do TextField, najprawdopodobniej zaimplementuje sposób prawidłowej manipulacji tekstem wieloliniowym.
Mitchell Walls,

36

W niektórych przypadkach wiąże się to ze sposobem użycia pola. W niektórych silnikach DB różnice w polu określają, w jaki sposób (i czy) szukać tekstu w polu. Pola CharField są zwykle używane do rzeczy, które można przeszukiwać, np. Jeśli chcesz wyszukać „jeden” w ciągu „jeden plus dwa”. Ponieważ ciągi są krótsze, wyszukiwanie silnika zajmuje mniej czasu. Pola tekstowe zwykle nie są przeszukiwane (jak może treść bloga), ale przeznaczone są do przechowywania dużych fragmentów tekstu. Teraz większość z nich zależy od silnika DB i podobnie jak w Postgresie nie ma to znaczenia.

Nawet jeśli to nie ma znaczenia, jeśli użyjesz ModelForms, w formularzu pojawi się inny typ pola edycji. ModelForm wygeneruje HTML o rozmiarze jednego wiersza tekstu dla CharField i multilinii dla TextField.


2
Jest to zdecydowanie najlepsze wytłumaczenie, ponieważ wspomina, jak generuje pole w formie. Charfield będzie tylko jednym wierszem wejściowym, ale TextField będzie wielowierszową skalowalną wielkością. TextField ma sens, gdy przede wszystkim implementujesz ogólne widoki klas. Działa świetnie dla pola opisu lub podobnego. Podoba mi się również to, jak renderbox wspomniał, że nie chcesz go używać do żadnych filtrów / wyszukiwań.
Mitchell Walls,

8

Na przykład.,. 2 pola są dodawane w modelu jak poniżej.

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

Poniżej znajdują się zapytania mysql wykonywane po zastosowaniu migracji.


dla TextField(opisu) pole jest zdefiniowane jakolongtext

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

Maksymalna długość TextFieldMySQL wynosi 4 GB zgodnie z przeglądem typu ciągu .


dla CharField(tytuł) maksymalna długość (wymagana) jest zdefiniowana jakovarchar(64)

ALTER TABLE `sometable_sometable` ADD COLUMN `title` varchar(64) NULL;
ALTER TABLE `sometable_sometable` ALTER COLUMN `title` DROP DEFAULT;

1
nit: dokumenty Django zalecają Avoid using null on string-based fields such as CharField and TextField:: docs.djangoproject.com/en/2.0/ref/models/fields/#null, więc najlepiej zachować null=False.
modulitos

7

CharFieldma maksymalną długość 255znaków, podczas gdy TextFieldmoże pomieścić więcej niż 255znaki. Użyj, TextFieldgdy masz duży ciąg jako dane wejściowe. Dobrze jest wiedzieć, że kiedy max_lengthparametr jest przekazywany do a TextField, przekazuje sprawdzanie poprawności długości do TextAreawidgetu.


„Wszelkie pola, które są przechowywane VARCHAR typami kolumn mają max_lengthograniczone do 255 znaków, jeśli używasz unikatowego = True dla pola. ” (Podkreślenie.)
l0b0

-4

Miałem dziwny problem i zrozumiałem nieprzyjemną dziwną różnicę: kiedy otrzymuję adres URL od użytkownika jako CharField, a następnie używam go w tagu HTML przez href, dodaje ten adres URL do mojego adresu URL i nie tego chcę. Ale kiedy robię to przez Textfield , przekazuje tylko adres URL wpisany przez użytkownika. spójrz na te: adres mojej strony:http://myweb.com

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

po kliknięciu: http://myweb.comhttp://some-address.com

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

po kliknięciu: http://some-address.com

Muszę wspomnieć, że adres URL jest zapisywany dokładnie tak samo w DB na dwa sposoby, ale nie wiem, dlaczego wynik jest inny po kliknięciu

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.