Джанго Чарфилд против TextField


302

В чем разница между CharField()и TextField()в Джанго? В документации сказано, что CharField()следует использовать для небольших строк и TextField()следует использовать для больших строк. Хорошо, но где проходит граница между «маленьким» и «большим»? Что здесь происходит под капотом, что делает это так?

Ответы:


354

Это разница между СУБД varchar(или аналогичными) - они обычно указываются с максимальной длиной и могут быть более эффективными с точки зрения производительности или хранения - и text(или аналогичными) типами - они обычно ограничиваются только жестко заданными пределами реализации (не Схема БД).

PostgreSQL 9, в частности, утверждает, что «между этими тремя типами нет различий в производительности» , но AFAIK есть некоторые различия, например, в MySQL, так что об этом следует помнить.

Хорошее практическое правило заключается в том, что вы используете, CharFieldкогда вам нужно ограничить максимальную длину, в TextFieldпротивном случае.

На самом деле это не относится к Джанго.


43
И наоборот, если вы используете CharField, то у вас должна быть максимальная длина
Сэм Свенбьоргхристиансенсен,

17
Я обнаружил, что использование TextFieldпо умолчанию может повлиять на переносимость вашего приложения. Возможно, производительность Postgres не снизится, но Oracle будет хранить ее как объект CLOB, вызывающий некоторые неудобства, например, невозможность использовать это поле в операторах WHERE. Просто кое-что рассмотреть.
Роб

3
Следует также учитывать, что в Oracle CharFieldне может быть max_lengthбольше 2000, или он выдает ORA-00910: specified length too long for its datatypeошибку.
Dinei

Полезно отметить, что при рассмотрении атрибутов полей документы Postgres также говорят (выделение мое): «максимально длинная строка символов, которую можно сохранить, составляет около 1 ГБ. (Максимальное значение, которое будет разрешено для n в объявлении типа данных, равно меньше этого [...] Если вы хотите хранить длинные строки без определенного верхнего предела, используйте текст или символ, изменяющийся без спецификатора длины, вместо того, чтобы задавать произвольный предел длины .) "
iff_or

3
Я считаю, что действительно важное различие между двумя в django заключается в том, как представление будет обрабатывать поле. В обычном режиме редактирования TextField будет отображаться как многострочный ввод большого размера; в то время как CharField является однострочным входом. Я не смотрел на исходный код django для TextField, но я собираюсь предположить, что если какой-либо сгенерированный html-файл будет прикреплен к TextField, то он, скорее всего, будет реализовывать способ правильной работы с многострочным текстом.
Митчелл Уоллс

36

В некоторых случаях это связано с тем, как используется поле. В некоторых механизмах БД различия полей определяют, как (и если) вы ищите текст в поле. CharFields обычно используются для поиска, например, если вы хотите найти «один» в строке «один плюс два». Поскольку строки короче, они занимают меньше времени для поиска движком. Текстовые поля обычно не предназначены для поиска (например, в теле блога), но предназначены для хранения больших кусков текста. Теперь большая часть этого зависит от БД Engine и, как в Postgres, это не имеет значения.

Даже если это не имеет значения, если вы используете ModelForms, вы получаете другой тип поля редактирования в форме. ModelForm сгенерирует форму HTML размером в одну строку текста для CharField и многострочным для TextField.


2
Это, безусловно, лучшее объяснение, потому что оно упоминает, как оно генерирует поле в форме. Charfield будет просто однострочным вводом, а TextField будет многострочным с изменяемым размером. TextField имеет смысл, когда вы в первую очередь реализуете общие представления классов. Это прекрасно работает для поля описания или тому подобное. Мне также нравится, как renderbox упоминал, что вы не захотите использовать его для каких-либо фильтров / поисков.
Митчелл Уоллс

8

Например, 2 поля добавляются в модель, как показано ниже.

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

Ниже приведены запросы mysql, выполняемые при переносе.


для TextField(описание) поле определяется какlongtext

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

Максимальная длина TextFieldMySQL составляет 4 ГБ в соответствии с обзором типа строки .


для CharField(title) max_length (обязательно) определяется какvarchar(64)

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

1
нит: Документы Джанго рекомендует: Avoid using null on string-based fields such as CharField and TextField: docs.djangoproject.com/en/2.0/ref/models/fields/#null так что лучше держать null=False.
modulitos

7

CharFieldимеет max_length 255символов, в то время как TextFieldможет содержать больше 255символов. Используйте, TextFieldкогда у вас есть большая строка в качестве ввода. Полезно знать, что когда max_lengthпараметр передается в a, TextFieldон передает проверку длины TextAreaвиджету.


«Любые поля, которые хранятся с VARCHARтипами столбцов, имеют max_lengthограничение до 255 символов, если вы используете для поля unique = True ». (Мое выделение.)
l0b0

-4

У меня была странная проблема, и я понял неприятную странную разницу: когда я получаю URL от пользователя как CharField, а затем и использую его в html теге href, он добавляет этот URL к моему URL, а это не то, что я хочу. Но когда я делаю это с помощью Textfield, он пропускает только тот URL, который ввел пользователь. посмотрите на это: мой адрес веб-сайта:http://myweb.com

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

при нажатии на него: http://myweb.comhttp://some-address.com

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

при нажатии на него: http://some-address.com

Я должен отметить, что URL-адрес сохраняется в БД одинаково двумя способами, но я не знаю, почему результат при нажатии на них отличается

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.