Поля формы¶
Когда вы создаете класс Form , наиболее важной частью является определение полей формы. Каждое поле имеет пользовательскую логику валидации, а также несколько других крючков.
Хотя основной способ использования классов Field — это классы Form , вы также можете инстанцировать их и использовать напрямую, чтобы лучше понять, как они работают. Каждый экземпляр Field имеет метод clean() , который принимает один аргумент и либо вызывает исключение django.core.exceptions.ValidationError , либо возвращает чистое значение:
Аргументы по основному полю¶
Каждый конструктор класса Field принимает по крайней мере эти аргументы. Некоторые классы Field принимают дополнительные, специфические для конкретной области аргументы, но следующие должны всегда приниматься:
required ¶
По умолчанию каждый класс Field предполагает, что значение является обязательным, поэтому если вы передадите пустое значение – либо None , либо пустую строку ( "" ) – то clean() вызовет исключение ValidationError :
Чтобы указать, что поле не обязательно, передайте required=False в конструктор Field :
Если Field имеет required=False и вы передаете clean() пустое значение, то clean() вернет нормализованное пустое значение, а не вызовет ValidationError . Для CharField это вернет empty_value , которое по умолчанию будет пустой строкой. Для других классов Field это может быть None . (Это зависит от конкретного поля).
Виджеты обязательных полей формы имеют HTML-атрибут required . Для отключения атрибута Form.use_required_attribute установите значение False . Атрибут required не включается в формы наборов форм, потому что валидация браузера может быть некорректной при добавлении и удалении наборов форм.
label ¶
Аргумент label позволяет указать «дружественную» для человека метку для этого поля. Она используется, когда Field отображается в Form .
Как объяснялось выше в разделе «Вывод форм в формате HTML», метка по умолчанию для Field формируется из имени поля путем преобразования всех знаков подчеркивания в пробелы и перевода первой буквы в верхний регистр. Укажите label , если это поведение по умолчанию не приводит к адекватной метке.
Вот полный пример Form , который реализует label для двух своих полей. Мы указали auto_id=False для упрощения вывода:
label_suffix ¶
Аргумент label_suffix позволяет вам переопределить label_suffix формы на основе каждого поля:
initial ¶
Аргумент initial позволяет указать начальное значение, которое будет использоваться при отображении данного Field в несвязанном Form .
Чтобы задать динамические начальные данные, см. параметр Form.initial .
Это нужно, когда вы хотите отобразить «пустую» форму, в которой поле инициализировано определенным значением. Например:
Вы можете подумать, почему бы просто не передать словарь начальных значений в качестве данных при отображении формы? Если вы сделаете это, то сработает валидация, и в HTML-вывод будут включены все ошибки валидации:
Именно поэтому значения initial отображаются только для несвязанных форм. Для связанных форм HTML-вывод будет использовать связанные данные.
Также обратите внимание, что значения initial не используются как «запасные» данные при валидации, если значение конкретного поля не задано. Значения initial предназначены только для начального отображения формы:
Вместо константы вы также можете передать любую вызываемую константу:
Вызываемый элемент будет оцениваться только при отображении несвязанной формы, а не при ее определении.
widget ¶
Аргумент widget позволяет указать класс Widget , который будет использоваться при рендеринге этого Field . Дополнительную информацию см. в разделе Виджеты .
help_text ¶
Аргумент help_text позволяет указать описательный текст для этого Field . Если вы укажете help_text , он будет отображаться рядом с Field , когда Field будет отображаться одним из удобных методов Form (например, as_ul() ).
Как и в случае с полем модели help_text , это значение не имеет HTML-выражения в автоматически генерируемых формах.
Вот полный пример Form , который реализует help_text для двух своих полей. Мы указали auto_id=False для упрощения вывода:
error_messages ¶
Аргумент error_messages позволяет вам переопределить сообщения по умолчанию, которые будет выдавать поле. Передайте словарь с ключами, соответствующими сообщениям об ошибках, которые вы хотите отменить. Например, вот сообщение об ошибке по умолчанию:
А вот пользовательское сообщение об ошибке:
В разделе built-in Field classes ниже каждый Field определяет ключи сообщения об ошибке, которые он использует.
validators ¶
Аргумент validators позволяет вам предоставить список функций валидации для этого поля.
Более подробную информацию см. в validators documentation .
localize ¶
Аргумент localize позволяет локализовать ввод данных формы, а также отображаемый вывод.
Для получения дополнительной информации см. документацию format localization .
disabled ¶
Булев аргумент disabled , когда он установлен в True , отключает поле формы, использующее HTML-атрибут disabled , так что оно не будет редактироваться пользователями. Даже если пользователь изменит значение поля, переданное на сервер, оно будет проигнорировано в пользу значения из исходных данных формы.
Проверка, изменились ли данные поля¶
has_changed() ¶
Метод has_changed() используется для определения того, изменилось ли значение поля по сравнению с начальным значением. Возвращает True или False .
Для получения дополнительной информации см. документацию Form.has_changed() .
Встроенные классы Field ¶
Естественно, библиотека forms поставляется с набором классов Field , которые представляют общие потребности валидации. В этом разделе документируется каждое встроенное поле.
Для каждого поля мы описываем виджет по умолчанию, используемый, если вы не указали widget . Мы также указываем значение, возвращаемое при предоставлении пустого значения (см. раздел required выше, чтобы понять, что это значит).
BooleanField ¶
- Виджет по умолчанию: CheckboxInput
- Пустое значение: False
- Нормализуется до: Значение Python True или False .
- Проверяет, что значение True (например, флажок установлен), если поле имеет значение required=True .
- Клавиши сообщения об ошибке: required
Поскольку все подклассы Field по умолчанию имеют required=True , условие проверки здесь очень важно. Если вы хотите включить в форму булево значение, которое может быть либо True , либо False (например, установленный или снятый флажок), вы должны не забыть передать required=False при создании BooleanField .
CharField ¶
- Виджет по умолчанию: TextInput
- Пустое значение: То, что вы указали как empty_value .
- Нормализуется до: Строка.
- Использует MaxLengthValidator и MinLengthValidator , если предоставлены max_length и min_length . В противном случае все входы действительны.
- Клавиши сообщений об ошибках: required , max_length , min_length
Имеет четыре необязательных аргумента для проверки:
Если эти аргументы указаны, они гарантируют, что строка имеет длину не более или не менее заданной.
Если True (по умолчанию), значение будет очищено от ведущих и последующих пробелов.
Значение, используемое для представления «пусто». По умолчанию это пустая строка.
ChoiceField ¶
- Виджет по умолчанию: Select
- Пустое значение: » (пустая строка).
- Нормализуется до: Строка.
- Проверяет наличие заданного значения в списке вариантов.
- Клавиши сообщений об ошибках: required , invalid_choice
Сообщение об ошибке invalid_choice может содержать %(value)s , которое будет заменено на выбранный вариант.
Принимает один дополнительный аргумент:
Либо iterable из 2-кортежей, которые будут использоваться в качестве вариантов для этого поля, либо enumeration вариантов, либо итерабель, возвращающая такую итерабель. Этот аргумент принимает те же форматы, что и аргумент choices для поля модели. Более подробную информацию см. в model field reference documentation on choices . Если аргумент является вызываемой переменной, он оценивается каждый раз при инициализации формы поля, а также во время рендеринга. По умолчанию используется пустой список.
TypedChoiceField ¶
Как и ChoiceField , за исключением того, что TypedChoiceField принимает два дополнительных аргумента, coerce и empty_value .
- Виджет по умолчанию: Select
- Пустое значение: То, что вы указали как empty_value .
- Нормализуется до: Значение типа, указанного в аргументе coerce .
- Проверяет, что заданное значение существует в списке вариантов и может быть принудительно введено.
- Клавиши сообщений об ошибках: required , invalid_choice
Принимает дополнительные аргументы:
Функция, которая принимает один аргумент и возвращает принудительное значение. Примеры включают встроенные int , float , bool и другие типы. По умолчанию используется функция тождества. Обратите внимание, что принуждение происходит после проверки ввода, поэтому возможно принуждение к значению, отсутствующему в choices .
Значение, используемое для обозначения «пусто». По умолчанию — пустая строка; None — другой распространенный вариант. Заметьте, что это значение не будет принудительно использоваться функцией, заданной в аргументе coerce , поэтому выбирайте его соответствующим образом.
DateField ¶
- Виджет по умолчанию: DateInput
- Пустое значение: None
- Нормализуется до: Объект Python datetime.date .
- Проверяет, что заданное значение является либо datetime.date , datetime.datetime , либо строкой, отформатированной в определенном формате даты.
- Клавиши сообщений об ошибках: required , invalid
Принимает один необязательный аргумент:
Список форматов, используемых для попытки преобразования строки в допустимый объект datetime.date .
Если аргумент input_formats не указан, форматы ввода по умолчанию берутся из DATE_INPUT_FORMATS , если USE_L10N является False , или из активного формата локали DATE_INPUT_FORMATS , если локализация включена. См. также format localization .
DateTimeField ¶
- Виджет по умолчанию: DateTimeInput
- Пустое значение: None
- Нормализуется до: Объект Python datetime.datetime .
- Проверяет, что заданное значение является либо datetime.datetime , datetime.date , либо строкой, отформатированной в определенном формате времени даты.
- Клавиши сообщений об ошибках: required , invalid
Принимает один необязательный аргумент:
Список форматов, используемых для попытки преобразования строки в допустимый объект datetime.datetime , в дополнение к форматам ISO 8601.
Поле всегда принимает строки в формате ISO 8601 в виде дат или аналогичных, распознаваемых parse_datetime() . Некоторые примеры:
Если аргумент input_formats не указан, форматы ввода по умолчанию берутся из DATETIME_INPUT_FORMATS и DATE_INPUT_FORMATS , если USE_L10N является False , или из активного формата локали DATETIME_INPUT_FORMATS и ключей DATE_INPUT_FORMATS , если локализация включена. См. также format localization .
DecimalField ¶
- Виджет по умолчанию: NumberInput , если Field.localize — False , иначе TextInput .
- Пустое значение: None
- Нормализуется до: A Python decimal .
- Проверяет, что заданное значение является десятичной дробью. Использует MaxValueValidator и MinValueValidator , если указаны max_value и min_value . Ведущие и последующие пробельные символы игнорируются.
- Клавиши сообщений об ошибках: required , invalid , max_value , min_value , max_digits , max_decimal_places , max_whole_digits
Сообщения об ошибках max_value и min_value могут содержать %(limit_value)s , которое будет заменено соответствующим пределом. Аналогично, сообщения об ошибках max_digits , max_decimal_places и max_whole_digits могут содержать %(max)s .
Принимает четыре необязательных аргумента:
Они контролируют диапазон значений, допустимых в поле, и должны быть заданы как значения decimal.Decimal .
Максимальное количество цифр (цифры до десятичной точки плюс цифры после десятичной точки, с вычеркнутыми ведущими нулями), допустимое в значении.
Максимально допустимое количество знаков после запятой.
DurationField ¶
- Виджет по умолчанию: TextInput
- Пустое значение: None
- Нормализуется до: A Python timedelta .
- Проверяет, что заданное значение является строкой, которая может быть преобразована в timedelta . Значение должно быть между datetime.timedelta.min и datetime.timedelta.max .
- Клавиши сообщений об ошибках: required , invalid , overflow .
Принимает любой формат, понимаемый parse_duration() .
EmailField ¶
- Виджет по умолчанию: EmailInput
- Пустое значение: То, что вы указали как empty_value .
- Нормализуется до: Строка.
- Использует EmailValidator для проверки того, что заданное значение является действительным адресом электронной почты, используя умеренно сложное регулярное выражение.
- Клавиши сообщений об ошибках: required , invalid
Имеет три необязательных аргумента max_length , min_length и empty_value , которые работают так же, как и для CharField .
FileField ¶
- Виджет по умолчанию: ClearableFileInput
- Пустое значение: None
- Нормализуется до: Объект UploadedFile , который объединяет содержимое файла и имя файла в один объект.
- Может подтвердить, что к форме были привязаны непустые данные файла.
- Клавиши сообщений об ошибках: required , invalid , missing , empty , max_length
Имеет два необязательных аргумента для проверки, max_length и allow_empty_file . Если они указаны, то гарантируют, что имя файла не более заданной длины, и что проверка пройдет успешно, даже если содержимое файла пусто.
Чтобы узнать больше об объекте UploadedFile , смотрите file uploads documentation .
Когда вы используете FileField в форме, вы также должны помнить о bind the file data to the form .
Ошибка max_length относится к длине имени файла. В сообщении об ошибке для этой клавиши %(max)d будет заменено на максимальную длину имени файла, а %(length)d — на текущую длину имени файла.
FilePathField ¶
- Виджет по умолчанию: Select
- Пустое значение: » (пустая строка).
- Нормализуется до: Строка.
- Проверяет наличие выбранного варианта в списке вариантов.
- Клавиши сообщений об ошибках: required , invalid_choice
Поле позволяет выбирать из файлов внутри определенного каталога. Оно принимает пять дополнительных аргументов; только path является обязательным:
Абсолютный путь к каталогу, содержимое которого вы хотите перечислить. Этот каталог должен существовать.
Если False (по умолчанию), то в качестве вариантов выбора будет предложено только непосредственное содержимое каталога path . Если True , каталог будет спускаться рекурсивно, и все потомки будут перечислены в качестве вариантов выбора.
Шаблон регулярного выражения; только файлы с именами, совпадающими с этим выражением, будут допущены в качестве вариантов выбора.
Необязательно. Либо True , либо False . По умолчанию True . Указывает, должны ли быть включены файлы в указанном месте. Либо это, либо allow_folders должно быть True .
Необязательно. Либо True , либо False . По умолчанию False . Указывает, должны ли включаться папки в указанном месте. Либо это, либо allow_files должно быть True .
FloatField ¶
- Виджет по умолчанию: NumberInput , если Field.localize — False , иначе TextInput .
- Пустое значение: None
- Нормализуется до: Python float.
- Проверяет, что заданное значение является float. Использует MaxValueValidator и MinValueValidator , если заданы max_value и min_value . Допускается использование пробелов в начале и в конце строки, как в функции Python float() .
- Клавиши сообщений об ошибках: required , invalid , max_value , min_value
Принимает два необязательных аргумента для проверки, max_value и min_value . Они управляют диапазоном значений, допустимых в поле.
ImageField ¶
- Виджет по умолчанию: ClearableFileInput
- Пустое значение: None
- Нормализуется до: Объект UploadedFile , который объединяет содержимое файла и имя файла в один объект.
- Проверяет, что данные файла были привязаны к форме. Также использует FileExtensionValidator для проверки того, что расширение файла поддерживается Pillow.
- Клавиши сообщений об ошибках: required , invalid , missing , empty , invalid_image
Использование ImageField требует, чтобы Pillow был установлен с поддержкой форматов изображений, которые вы используете. Если при загрузке изображения вы столкнулись с ошибкой corrupt image , это обычно означает, что Pillow не понимает его формат. Чтобы исправить это, установите соответствующую библиотеку и переустановите Pillow.
Когда вы используете ImageField на форме, вы также должны помнить о bind the file data to the form .
После очистки и проверки поля объект UploadedFile будет иметь дополнительный атрибут image , содержащий экземпляр Pillow Image, используемый для проверки того, является ли файл действительным изображением. Pillow закрывает базовый дескриптор файла после проверки изображения, поэтому, хотя атрибуты, не относящиеся к данным изображения, такие как format , height и width , доступны, методы, обращающиеся к базовым данным изображения, такие как getdata() или getpixel() , не могут быть использованы без повторного открытия файла. Например:
Кроме того, UploadedFile.content_type будет обновлен типом содержимого изображения, если Pillow сможет его определить, в противном случае он будет установлен в None .
IntegerField ¶
- Виджет по умолчанию: NumberInput , если Field.localize — False , иначе TextInput .
- Пустое значение: None
- Нормализуется до: Целое число Python.
- Проверяет, что заданное значение является целым числом. Использует MaxValueValidator и MinValueValidator , если заданы max_value и min_value . Допускается использование пробелов в начале и в конце строки, как в функции Python int() .
- Клавиши сообщений об ошибках: required , invalid , max_value , min_value
Сообщения об ошибках max_value и min_value могут содержать %(limit_value)s , которое будет заменено соответствующим пределом.
Принимает два необязательных аргумента для проверки:
Они управляют диапазоном значений, допустимых в поле.
JSONField ¶
Поле, которое принимает данные в кодировке JSON для JSONField .
- Виджет по умолчанию: Textarea
- Пустое значение: None
- Нормализуется до: Python-представление значения JSON (обычно в виде dict , list или None ), в зависимости от JSONField.decoder .
- Проверяет, что заданное значение является допустимым JSON.
- Клавиши сообщений об ошибках: required , invalid
Принимает два необязательных аргумента:
Подкласс json.JSONEncoder для сериализации типов данных, не поддерживаемых стандартным сериализатором JSON (например, datetime.datetime или UUID ). Например, вы можете использовать класс DjangoJSONEncoder .
По умолчанию используется json.JSONEncoder .
Подкласс json.JSONDecoder для десериализации входных данных. Десериализация может потребовать учета того факта, что вы не можете быть уверены в типе входных данных. Например, вы рискуете вернуть datetime , который на самом деле был строкой, просто имеющей тот же формат, который выбран для datetime s.
decoder может использоваться для проверки ввода. Если во время десериализации возникает ошибка json.JSONDecodeError , то возникает ошибка ValidationError .
По умолчанию используется json.JSONDencoder .
Если вы используете ModelForm , будут использованы encoder и decoder из JSONField .
Удобные для пользователя формы
JSONField в большинстве случаев не очень удобен для пользователя. Однако это полезный способ форматирования данных из виджета на стороне клиента для отправки на сервер.
GenericIPAddressField ¶
Поле, содержащее либо IPv4, либо IPv6-адрес.
- Виджет по умолчанию: TextInput
- Пустое значение: » (пустая строка).
- Нормализуется до: Строка. Адреса IPv6 нормализуются, как описано ниже.
- Проверяет, что заданное значение является действительным IP-адресом.
- Клавиши сообщений об ошибках: required , invalid
Нормализация адресов IPv6 следует RFC 4291#section-2.2 разделу 2.2, включая использование формата IPv4, предложенного в параграфе 3 этого раздела, как ::ffff:192.0.2.0 . Например, 2001:0::0:01 будет нормализован до 2001::1 , а ::ffff:0a0a:0a0a до ::ffff:10.10.10.10 . Все символы преобразуются в строчные.
Принимает два необязательных аргумента:
Ограничивает допустимые входы указанным протоколом. Принимаемые значения: both (по умолчанию), IPv4 или IPv6 . Соответствие нечувствительно к регистру.
Распаковывает сопоставленные адреса IPv4 как ::ffff:192.0.2.1 . Если опция включена, то адрес будет распакован в 192.0.2.1 . По умолчанию отключена. Может использоваться только в том случае, если protocol установлено в ‘both’ .
MultipleChoiceField ¶
- Виджет по умолчанию: SelectMultiple
- Пустое значение: [] (пустой список).
- Нормализуется до: Список строк.
- Проверяет, что каждое значение из заданного списка значений существует в списке вариантов.
- Клавиши сообщений об ошибках: required , invalid_choice , invalid_list
Сообщение об ошибке invalid_choice может содержать %(value)s , которое будет заменено на выбранный вариант.
Принимает один дополнительный обязательный аргумент choices , как и ChoiceField .
TypedMultipleChoiceField ¶
Как и MultipleChoiceField , за исключением того, что TypedMultipleChoiceField принимает два дополнительных аргумента, coerce и empty_value .
- Виджет по умолчанию: SelectMultiple
- Пустое значение: То, что вы указали как empty_value
- Нормализуется до: Список значений того типа, который указан в аргументе coerce .
- Проверяет, что заданные значения существуют в списке вариантов и могут быть принудительно введены.
- Клавиши сообщений об ошибках: required , invalid_choice
Сообщение об ошибке invalid_choice может содержать %(value)s , которое будет заменено на выбранный вариант.
Принимает два дополнительных аргумента, coerce и empty_value , как и для TypedChoiceField .
NullBooleanField ¶
- Виджет по умолчанию: NullBooleanSelect
- Пустое значение: None
- Нормализуется до: Значение Python True , False или None .
- Ничего не проверяет (т.е. никогда не выдает ошибку ValidationError ).
NullBooleanField можно использовать с такими виджетами, как Select или RadioSelect , предоставив виджет choices :
RegexField ¶
- Виджет по умолчанию: TextInput
- Пустое значение: То, что вы указали как empty_value .
- Нормализуется до: Строка.
- Использует RegexValidator для проверки соответствия заданного значения определенному регулярному выражению.
- Клавиши сообщений об ошибках: required , invalid
Принимает один необходимый аргумент:
Регулярное выражение, заданное либо как строка, либо как скомпилированный объект регулярного выражения.
Также принимает max_length , min_length , strip и empty_value , которые работают так же, как и для CharField .
По умолчанию имеет значение False . Если включено, отсечение будет применяться перед проверкой regex.
SlugField ¶
- Виджет по умолчанию: TextInput
- Пустое значение: То, что вы указали как empty_value .
- Нормализуется до: Строка.
- Использует validate_slug или validate_unicode_slug для проверки того, что заданное значение содержит только буквы, цифры, подчеркивания и дефисы.
- Сообщения об ошибках: required , invalid
Это поле предназначено для использования при представлении модели SlugField в формах.
Принимает два необязательных параметра:
Булево значение, указывающее полю принимать буквы Unicode в дополнение к буквам ASCII. По умолчанию имеет значение False .
Значение, используемое для представления «пусто». По умолчанию это пустая строка.
TimeField ¶
- Виджет по умолчанию: TimeInput
- Пустое значение: None
- Нормализуется до: Объект Python datetime.time .
- Проверяет, что заданное значение является либо datetime.time , либо строкой, отформатированной в определенном формате времени.
- Клавиши сообщений об ошибках: required , invalid
Принимает один необязательный аргумент:
Список форматов, используемых для попытки преобразования строки в допустимый объект datetime.time .
Если аргумент input_formats не указан, форматы ввода по умолчанию берутся из TIME_INPUT_FORMATS , если USE_L10N является False , или из активного формата локали TIME_INPUT_FORMATS , если локализация включена. См. также format localization .
URLField ¶
- Виджет по умолчанию: URLInput
- Пустое значение: То, что вы указали как empty_value .
- Нормализуется до: Строка.
- Использует URLValidator для проверки того, что заданное значение является действительным URL.
- Клавиши сообщений об ошибках: required , invalid
Имеет три необязательных аргумента max_length , min_length и empty_value , которые работают так же, как и для CharField .
UUIDField ¶
- Виджет по умолчанию: TextInput
- Пустое значение: None
- Нормализуется до: Объект UUID .
- Клавиши сообщений об ошибках: required , invalid
Это поле принимает любой формат строки, принятый в качестве аргумента hex в конструкторе UUID .
Немного сложные встроенные Field классы¶
ComboField ¶
- Виджет по умолчанию: TextInput
- Пустое значение: » (пустая строка).
- Нормализуется до: Строка.
- Проверяет заданное значение по каждому из полей, указанных в качестве аргумента в ComboField .
- Клавиши сообщений об ошибках: required , invalid
Принимает один дополнительный необходимый аргумент:
Список полей, которые должны быть использованы для проверки значения поля (в порядке их предоставления).
MultiValueField ¶
- Виджет по умолчанию: TextInput
- Пустое значение: » (пустая строка).
- Нормализуется до: тип, возвращаемый методом compress подкласса.
- Проверяет заданное значение по каждому из полей, указанных в качестве аргумента в MultiValueField .
- Клавиши сообщений об ошибках: required , invalid , incomplete
Агрегирует логику нескольких полей, которые вместе дают одно значение.
Это поле является абстрактным и должно быть подклассом. В отличие от полей с одним значением, подклассы MultiValueField не должны реализовывать clean() , а вместо этого — реализовывать compress() .
Принимает один дополнительный необходимый аргумент:
Кортеж полей, значения которых очищаются и впоследствии объединяются в одно значение. Каждое значение поля очищается соответствующим полем в fields – первое значение очищается первым полем, второе значение очищается вторым полем и т.д. Когда все поля очищены, список чистых значений объединяется в одно значение по compress() .
Также принимает некоторые необязательные аргументы:
По умолчанию установлено значение True , в этом случае будет выдана ошибка валидации required , если для какого-либо поля не указано значение.
Если установлено значение False , атрибут Field.required может быть установлен в значение False для отдельных полей, чтобы сделать их необязательными. Если для обязательного поля не указано значение, будет выдана ошибка валидации incomplete .
Сообщение об ошибке по умолчанию incomplete может быть определено для подкласса MultiValueField , или могут быть определены различные сообщения для каждого отдельного поля. Например:
Должен быть подклассом django.forms.MultiWidget . Значение по умолчанию TextInput , что, вероятно, не очень полезно в данном случае.
Принимает список допустимых значений и возвращает «сжатую» версию этих значений — в одном значении. Например, SplitDateTimeField является подклассом, который объединяет поле времени и поле даты в объект datetime .
Этот метод должен быть реализован в подклассах.
SplitDateTimeField ¶
- Виджет по умолчанию: SplitDateTimeWidget
- Пустое значение: None
- Нормализуется до: Объект Python datetime.datetime .
- Проверяет, что заданное значение является datetime.datetime или строкой, отформатированной в определенном формате времени даты.
- Клавиши сообщений об ошибках: required , invalid , invalid_date , invalid_time
Принимает два необязательных аргумента:
Список форматов, используемых для попытки преобразования строки в допустимый объект datetime.date .
Если аргумент input_date_formats не указан, используются форматы ввода по умолчанию для DateField .
Список форматов, используемых для попытки преобразования строки в допустимый объект datetime.time .
Если аргумент input_time_formats не указан, используются форматы ввода по умолчанию для TimeField .
Поля, которые обрабатывают отношения¶
Для представления отношений между моделями доступны два поля: ModelChoiceField и ModelMultipleChoiceField . Оба эти поля требуют одного параметра queryset , который используется для создания вариантов для поля. При проверке формы эти поля помещают либо один объект модели (в случае ModelChoiceField ), либо несколько объектов модели (в случае ModelMultipleChoiceField ) в словарь cleaned_data формы.
Для более сложного использования можно указать queryset=None при объявлении поля формы и затем заполнить queryset в методе __init__() формы:
И ModelChoiceField , и ModelMultipleChoiceField имеют атрибут iterator , который определяет класс, используемый для итерации по набору запросов при генерации вариантов. Подробности см. в разделе Итерация выбора отношений .
ModelChoiceField ¶
- Виджет по умолчанию: Select
- Пустое значение: None
- Нормализуется до: Экземпляр модели.
- Проверяет, существует ли заданный id в наборе запросов.
- Клавиши сообщений об ошибках: required , invalid_choice
Сообщение об ошибке invalid_choice может содержать %(value)s , которое будет заменено на выбранный вариант.
Позволяет выбрать один объект модели, подходящий для представления внешнего ключа. Обратите внимание, что виджет по умолчанию ModelChoiceField становится непрактичным при увеличении количества записей. Вы должны избегать его использования для более чем 100 элементов.
Требуется один аргумент:
Объект модели QuerySet >, из которого берутся варианты выбора для поля и который используется для проверки выбора пользователя. Он оценивается при отображении формы.
ModelChoiceField также принимает два необязательных аргумента:
По умолчанию виджет <select> , используемый ModelChoiceField , будет иметь пустой выбор в верхней части списка. Вы можете изменить текст этой метки (который по умолчанию равен "———" ) с помощью атрибута empty_label , или вы можете полностью отключить пустую метку, установив empty_label в None :
Обратите внимание, что если требуется ModelChoiceField и имеет начальное значение по умолчанию, то пустой выбор не создается (независимо от значения empty_label ).
Этот необязательный аргумент используется для указания поля, которое будет использоваться в качестве значения выбора в виджете поля. Убедитесь, что это уникальное поле для модели, иначе выбранное значение может соответствовать более чем одному объекту. По умолчанию оно установлено в None , в этом случае будет использоваться первичный ключ каждого объекта. Например:
Модели в Django 3
Модель — это класс, который содержит одну таблицу в вашей базе данных. Каждая модель представляет собой подклассы Python django.db.models.Model, а каждый атрибут модели, представляет собой отдельную запись в базе данных. Чтобы модели были успешно обработаны Django, содержащие их приложения должный быть зарегистрированы в списке приложений проекта.
Приведем пример модели Django. В этом примере модели, описывается класс Student , у которого есть имя ( first_name ) и фамилия ( last_name ):
first_name и last_name являются полями модели. Каждое поле указывается как атрибут класса, и каждый атрибут сопоставляется со столбцом базы данных.
Модель Student создает вот такую таблицу базе данных:
1. Аргументы, доступные для всех типов полей Django
Если True, Django будет хранить пустые значения, как NULL в базе данных. По умолчанию False.
Избегайте использования null в строковых полях, таких как CharField и TextField . Если строковое поле имеет null =True , это означает, что у него есть два возможных значения для «нет данных»: NULL и пустая строка. В большинстве случаев иметь два возможных значения для «нет данных» излишне; соглашение Django заключается в использовании пустой строки, а не NULL. Единственное исключение — это когда CharField оба параметра unique=True и blank=True установлены. В этой ситуации null =True требуется избежать нарушения уникальных ограничений при сохранении нескольких объектов с пустыми значениями.
Как для строковых, так и для нестроковых полей вам также потребуется установить, blank=True, если вы хотите разрешить пустые значения в формах, поскольку null параметр влияет только на хранилище базы данных.
blank
Если True, то Django позволит занести в поле пустое значение, в таком случае поле станет не обязательным к заполнению. По умолчанию False.
Обратите внимание, что blank отличается от null. null связано исключительно с базой данных, тогда как blank связано с проверкой. Если в поле есть blank=True , проверка формы позволит ввести пустое значение. Если в поле есть blank=False , поле будет обязательным.
verbose_name
Удобочитаемое (" человеческое ") имя поля. Если имя не указано, то Django автоматически создаст его, используя имя атрибута поля, преобразовав подчеркивание в пробелы.
help_text
Дополнительный поясняющий текст, отображаемый в виджете формы. Это полезно для документации, даже если ваше поле не используется в форме.
Обратите внимание, что это значение не экранируется HTML в автоматически сгенерированных формах и выводится как есть. Например:
db_column
Имя столбца базы данных, используемого для этого поля. Если это не указано, Django будет использовать имя поля.
Если имя столбца вашей базы данных является зарезервированным словом SQL или содержит символы, недопустимые в именах переменных Python, в частности дефис — это нормально. Django цитирует имена столбцов и таблиц за кулисами.
db_index
Если True, для этого поля будет создан индекс базы данных.
db_tablespace
Имя табличного пространства базы данных, которое будет использоваться для индекса этого поля, если это поле проиндексировано. По умолчанию используется параметр проекта DEFAULT_INDEX_TABLESPACE, если он установлен, или db_tablespace параметр модели, если он есть. Если серверная часть не поддерживает табличные пространства для индексов, этот параметр игнорируется.
default
Значение по умолчанию записываемое в поле. Это может быть значение или вызываемый объект. Если записывается вызываемый объект, он будет вызываться каждый раз при создании нового объекта.
editable
Если False, поле не будет отображаться ни в админке, ни в каком-либо другом ModelForm. Они также пропускаются во время проверки модели . По умолчанию True.
primary_key
Если True — это поле является первичным ключом модели.
Если вы не укажете primary_key =True в какое-либо поле своей модели, то Django автоматически добавит его в поле для хранения первичного ключа, поэтому вам не нужно устанавливать primary_key =True в какие-либо поля, если вы не хотите переопределить поведение первичного ключа по умолчанию. Тип автоматически создаваемых полей первичного ключа можно указать для каждого приложения AppConfig.default_auto_field или глобально в DEFAULT_AUTO_FIELD в настройках.
primary_key=True подразумевает что null=False и unique=True . Для объекта разрешен только один первичный ключ.
Поле первичного ключа доступно только для чтения. Если вы измените значение первичного ключа на существующем объекте, а затем сохраните его, новый объект будет создан рядом со старым.
unique
Если True, то в это поле должно быть занесено уникальное в пределах таблицы значение.
Это обеспечивается на уровне базы данных и проверкой модели. Если вы попытаетесь сохранить модель с повторяющимся значением в unique поле, то будет возбуждено исключение django.db.IntegrityError .
Эта опция действительна для всех типов полей, кроме ManyToManyField и OneToOneField.
Обратите внимание: когда unique =True , то указывать db_index не нужно, поскольку unique подразумевает создание индекса.
unique_for_date
Задайте для него имя DateField или DateTimeField, чтобы это поле было уникальным для значения поля даты.
Например, если у вас есть поле title, в котором есть unique_for_date ="pub_date" , то Django не разрешит ввод двух записей с одинаковыми title и pub_date.
unique_for_month
То же самое, что и unique_for_date, но в расчет принимается только месяц.
unique_for_year
То же самое что unique_for_date и unique_for_month, но в расчет принимается год.
error_messages
error_messages , аргумент позволяет переопределить сообщения по умолчанию , что поле будет выводить. Передайте словарь с ключами, соответствующими сообщениям об ошибках, которые вы хотите переопределить.
Ключи сообщений об ошибках включают в себя null, blank, invalid, invalid_choice, unique, и unique_for_date. Дополнительные ключи сообщений об ошибках указаны для каждого поля в разделе Типы полей ниже.
2. Типы полей моделей Django
Каждое поле хранит значения определенного типа. Почти все поля поддерживают аргументы описанные раньше.
TextField
class TextField (**параметры)
Текстовое поле неограниченной длины. Рекомендуется применять для сохранения больших объемов текста. Поддерживает необязательный параметр max_length . Если он не указан, то можно записать значение любой длины.
context = models. TextField (max_length=5000)
CharField
class CharField ( max_length = None , ** параметры )
Строковое поле для строк от маленького до большого. Для больших объемов текста используйте TextField. CharField имеет один дополнительный обязательный аргумент max_length.
max_length — указывает максимальную длину заносимого в поле значения.
title = models. CharField (max_length=30)
EmailField
class EmailField (max_length=254, **параметры)
Адрес электронной почты в строковом виде. Поддерживает необязательный параметр max_length . По умолчанию стоит 254.
AutoField
class AutoField ( ** параметры )
Значение IntegerField, которое автоматически увеличивается в соответствии с доступными идентификаторами. Обычно вам не нужно использовать это напрямую Поле первичного ключа будет автоматически добавлено в вашу модель, если вы не укажете иное.
BigAutoField
class BigAutoField (**параметры)
64-битное целое число, тоже самое что и AutoField, за исключением того, что оно гарантированно соответствует числам от 1до 9223372036854775807.
BigIntegerField
class BigIntegerField (**параметры)
64-битное целое число, тоже самое что и IntegerField, за исключением того, что оно гарантированно соответствует числам от -9223372036854775808 до 9223372036854775807.
BinaryField
class BinaryField (max_length=None, **параметры)
Поле для хранения необработанных двоичных данных. Он может быть назначен bytes, bytearray или memoryview. По умолчанию BinaryField устанавливает editable на False, в этом случае она не может быть включена в ModelForm. BinaryField имеет один дополнительный необязательный аргумент max_length .
BooleanField
class BooleanField (**параметры)
Поле хранящее значение True или False. Значение по умолчанию None, а не False.
DateField
class DateField ( auto_now = False , auto_now_add = False , ** параметры )
Дата, представленная в Python datetime.date экземпляром. Имеет несколько дополнительных необязательных аргументов:
— DateField.auto_now
Автоматически при каждом сохранение записи будет устанавливаться текущее время.
— DateField.auto_now_add
Автоматически устанавливает текущую дату только при создание записи. В последующем при изменение дата не меняется.
DateTimeField
class DateTimeField ( auto_now = False , auto_now_add = False , ** параметры )
Дата и время, представленные в Python datetime.datetime экземпляром. Принимает те же дополнительные аргументы, что и DateField. Виджет формы по умолчанию для этого поля — одиночный DateTimeInput.
DecimalField
class DecimalField ( max_digits = None , decimal_places = None , ** параметры )
Десятичное число фиксированной точности, представленное в Python Decimal экземпляром. Он проверяет ввод с помощью DecimalValidator.
Имеет два обязательных аргумента:
— DecimalField.max_digits
Максимально допустимое количество цифр в номере. Обратите внимание, что это число должно быть больше или равно decimal_places.
— DecimalField.decimal_places
Количество десятичных знаков, которые нужно сохранить вместе с номером.
Например, для хранения чисел 999 с разрешением до 2 знаков после запятой вы должны использовать:
models. DecimalField (. max_digits=5, decimal_places=2)
И для хранения чисел примерно до одного миллиарда с разрешением до 10 знаков после запятой:
models. DecimalField (. max_digits=19, decimal_places=10)
DurationField
class DurationField ( ** параметры )
Поле для хранения периодов времени — смоделировано на Python с помощью timedelta. При использовании в PostgreSQL используется тип данных, intervalа в Oracle тип данных . В противном случае используется микросекунды. INTERVAL DAY(9) TO SECOND(6)bigint
IntegerField
class IntegerField ( ** параметры )
Целое число ( 32 разрядное ) . Значения от -2147483648 до 2147483647 безопасны во всех базах данных, поддерживаемых Django. Он использует MinValueValidator и MaxValueValidator для проверки ввода на основе значений, поддерживаемых базой данных по умолчанию.
GenericIPAddressField
class GenericIPAddressField ( протокол = 'both' , unpack_ipv4 = False , ** параметры )
IP-адрес записанный по для протокола IPv4 или IPv6 в виде строки. Поддерживает два необязательных параметра:
— GenericIPAddressField.protocol
Ограничивает допустимые входные данные указанным протоколом. Допустимые значения: 'both'(по умолчанию) 'IPv4' или 'IPv6'. При сопоставлении регистр не учитывается.
— GenericIPAddressField.unpack_ipv4
Распаковывает сопоставленные адреса IPv4, например ::ffff:192.0.2.1. Если эта опция включена, этот адрес будет распакован 192.0.2.1. По умолчанию отключено. Может использоваться, только если для параметра protocol установлено значение 'both'.
PositiveBigIntegerField
class PositiveBigIntegerField ( ** параметры)
Допускает значения только в определенной (зависящей от базы данных) точке. Значения от 0до 9223372036854775807 безопасны во всех базах данных, поддерживаемых Django.
PositiveIntegerField
class PositiveIntegerField ( ** параметры )
Должно быть либо положительным, либо нулевым ( 0). Значения от 0 до 2147483647 безопасны во всех базах данных, поддерживаемых Django. Значение 0 принято из соображений обратной совместимости.
PositiveSmallIntegerField
class PositiveSmallIntegerField ( ** параметры )
Допускает значения только в определенной (зависящей от базы данных) точке. Значения от 0 до 32767 безопасны во всех базах данных, поддерживаемых Django.
SlugField
class SlugField ( max_length = 50 , ** параметры )
Слаг — это короткая метка для чего-либо, содержащая только буквы, цифры, подчеркивания или дефисы. Обычно они используются в URL-адресах. Как и CharField, вы можете указать max_length . Если max_length не указано, Django будет использовать длину по умолчанию 50.
Часто бывает полезно автоматически предварительно заполнить SlugField на основе значения некоторого другого значения. Вы можете сделать это автоматически в админке с помощью prepopulated_fields .
Если True, поле принимает буквы Юникода в дополнение к буквам ASCII. По умолчанию False.
SmallAutoField
class SmallAutoField (**параметры)
Допускает значения только в пределах определенного (зависящего от базы данных) предела. Значения от 1 до 32767 безопасны во всех базах данных, поддерживаемых Django.
SmallIntegerField
class SmallIntegerField ( ** параметры )
Допускает значения только в определенной (зависящей от базы данных) точке. Значения от -32768 до 32767 безопасны во всех базах данных, поддерживаемых Django.
TimeField
class TimeField ( auto_now = False , auto_now_add = False , ** параметры )
Время, представленное в Python datetime.time экземпляром. Принимает те же параметры автозаполнения, что и DateField.
URLField
class URLField ( max_length = 200 , ** параметры )
Виджет формы по умолчанию для этого поля — файл URLInput.
Необязательный параметр max_length указывает максимальную длину заносимого в поле интернет-адреса. Значение по умолчанию 200.
UUIDField
class UUIDField ( ** параметры )
Поле для хранения универсальных уникальных идентификаторов. Использует UUIDкласс Python . При использовании в PostgreSQL хранится в uuidтипе данных, в противном случае — в файле char(32).
Универсальные уникальные идентификаторы — хорошая альтернатива AutoFieldfor primary_key. База данных не будет генерировать UUID для вас, поэтому рекомендуется использовать default:
Формы в Django
Последним, что нам стоит сделать для нашего веб-сайта, является удобный способ добавления и редактирования записей. admin -панель Django удобна, но её дизайн сложно изменять. С forms (формами) у нас будет абсолютная власть над интерфейсом блога — мы сможем сделать практически всё, что только можно придумать!
Формы Django удобны тем, что мы можем создать новую форму с нуля или воспользоваться ModelForm для сохранения содержимого формы в модель.
Это как раз то, что нам нужно сделать: мы создадим форму для модели Post .
Как и любая важная часть Django, формы имеют свой собственный файл: forms.py .
Нам нужно создать файл с таким именем в директории blog .
Теперь открой его и набери следующее:
Для начала нам нужно импортировать формы Django ( from django import forms ) и, разумеется, нашу модель Post ( from .models import Post ).
PostForm , как ты, вероятно, подозреваешь, — это имя для нашей формы. Нам нужно также сообщить Django, что эта форма относится к ModelForm (чтобы он смог поколдовать для нас) — forms.ModelForm поможет с этим.
Дальше у нас class Meta , где мы определяем, какая модель будет использоваться для создания формы ( model = Post ).
В завершение мы можем указать, какие поля должны присутствовать в нашей форме. Сейчас нам требуются только поля title и text — author будет автоматически выбран в зависимости от авторизованного пользователя (тебя), а created_date должна автоматически проставляться в момент создания записи (т.е. через код), верно?
Вот и всё! Теперь мы можем использовать форму в представлении и отобразить её в шаблоне.
Поэтому снова нам необходимо создать ссылку на страницу, URL-адрес, представление и шаблон.
Ссылка на страницу с формой
Пришло время открыть файл blog/templates/blog/base.html . Мы добавим ссылку в элемент div с именем page-header :
Обрати внимание, что мы назвали новое представление post_new . Класс glyphicon glyphicon-plus определён в используемой нами теме bootstrap — таким образом мы выведем значок плюса.
После добавления строки твой html-файл должен выглядеть следующим образом:
После сохранения файла и перезагрузки страницы по адресу http://127.0.0.1:8000 ты, конечно, увидишь знакомую ошибку NoReverseMatch , верно?
Нам нужно открыть файл blog/urls.py и добавить строку:
Окончательная версия файла будет выглядеть следующим образом:
После перезагрузки веб-сайта мы увидим ошибку AttributeError , поскольку представление post_new не реализовано. Давай добавим его прямо сейчас.
Представление post_new
Самое время открыть файл blog/views.py и добавить следующую строку к остальным, начинающимся с from :
А затем наше представление:
Чтобы создать новую форму Post , нам потребуется вызвать PostForm() и передать её шаблону. Мы ещё вернёмся к этому представлению, а пока давай быстро создадим шаблон под форму.
Шаблон
Нам нужно создать файл post_edit.html в директории blog/templates/blog . Чтобы заставить форму работать, нам потребуется несколько вещей:
- Нам нужно отобразить форму. Мы можем сделать это, к примеру, простым << form.as_p >> .
- Строка выше должна быть обёрнута в HTML-теги <form method="POST">. </form>
- Нам потребуется кнопка Save . Мы добавим её при помощи HTML-кнопки: <button type="submit">Save</button>
- И, наконец, сразу после открытия тега < form. > мы должны добавить <% csrf_token %>. Это очень важно, поскольку так мы делаем форму защищённой! Django будет ругаться, если ты забудешь добавить этот код:
Хорошо, давай посмотрим, как должен выглядеть HTML-код в файле post_edit.html :
Время обновить страницу! Ура! Форма отображается!
Но подожди минутку! Если ты наберёшь что-нибудь в полях title и text и попробуешь сохранить — что произойдёт?
Ничего! Мы снова на той же странице и наш текст пропал. и новая запись не была добавлена. Так что же пошло не так?
Ответ прост: ничего. Нам нужно сделать кое-что ещё, чтобы новое представление заработало.
Сохраняем данные из формы
Снова открой файл blog/views.py . Всё, что у нас есть в представлении post_new , выглядит пока следующим образом:
После отправки формы мы возвращаемся к тому же представлению, но в этот раз с новыми данными в request , а точнее, в request.POST (имя POST не имеет ничего общего с "постом" в блоге, оно связано с тем, что мы "публикуем" данные). Помнишь, что в HTML-файле определение <form> имеет параметр method="POST" ? Все поля формы теперь находятся в request.POST . Ты не должна переименовывать POST во что-то другое (другое доступное значение параметра method — GET , но у нас сейчас нет времени объяснять разницу).
Получается, что в представлении view нам нужно обработать две разные ситуации. Первая: когда мы только зашли на страницу и хотим получить пустую форму. Вторая: когда мы возвращаемся к представлению со всей информацией, которую мы ввели в форму. Таким образом, нам потребуется ввести условие (для этого мы будем использовать условный оператор if ):
Теперь заполним строку, занятую [. ] . Если method — POST , тогда мы хотим построить PostForm с данными из формы, верно? Мы добьёмся этого следующим образом:
Легко! Дальше мы проверим, корректна ли форма (все ли необходимые поля заполнены и не отправлено ли некорректных значений). Мы сделаем это при помощи form.is_valid() .
Мы проверяем, допустимо ли содержимое формы, и, если всё в порядке, сохраняем её!
Фактически мы выполняем две операции: сохраняем форму form.save и добавляем автора (поскольку обязательного поля author нет в PostForm !). commit=False означает, что мы пока не хотим сохранять модель Post — сначала нужно добавить автора. В основном ты будешь использовать form.save() , без commit=False , но в данном случае нам это пригодится. post.save() сохранит изменения (после добавления автора), и новая запись будет создана!
Наконец, будет прекрасно, если мы сможем сразу переходить к странице post_detail после добавления новой записи, согласна? Для этого нам понадобится еще один импорт:
Добавь эту строку в начало файла. Теперь мы можем сделать переадресацию на страницу post_detail для созданной записи:
post_detail — это имя представления, которое нам необходимо. Помнишь, что это представление требует переменную pk ? Чтобы передать её представлению, мы используем аргумент pk=post.pk , где post — это новая запись в блоге!
Хорошо, мы многое обсудили, пора взглянуть на представление полностью, верно?
Проверим, всё ли работает. Перейди по адресу http://127.0.0.1:8000/post/new/, добавь текст в поля title и text , затем сохрани… и вуаля! Новая запись создана, и мы перешли на страницу post_detail !
Возможно, ты заметила, что мы устанавливаем дату публикации перед сохранением поста. В последствии мы сделаем кнопку публикации в Django Girls Tutorial: Extensions.
Поскольку мы недавно использовали панель администратора Django, система до сих пор думает, что мы авторизованы. Существует несколько случаев, когда мы можем случайно выйти из аккаунта (закрытие браузера, перезапуск базы данных и т.д.). Если ты получаешь ошибку при попытке сохранения записи, то потребуется перейти на страницу http://127.0.0.1:8000/admin и авторизоваться в системе снова. Это решит проблему. В главе Домашнее задание: добавляем безопасность нашему веб-сайту! после основного учебника описано окончательное решение этой проблемы.
Валидация формы
Теперь мы покажем тебе, насколько круты формы в Django. Запись в блоге должна иметь поля title и text . В нашей модели Post мы не указываем, что эти поля необязательны (в отличие от published_date ), так что Django по умолчанию будет ожидать, что пользователь их заполнит.
Попробуй сохранить форму с незаполненными полями title и text . Угадай, что произойдёт!
Django заботится о проверке всех полей в нашей форме на корректность. Разве не шикарно?
Форма редактирования
Теперь мы знаем, как добавить новую форму. Но что, если мы хотим внести исправления в уже существующую запись? По сути это схожая с предыдущей задача. Давай быстро создадим пару важных вещей (если ты чего-то не понимаешь, спроси своего тренера или загляни в предыдущие главы, поскольку мы уже объясняли все необходимые шаги).
Открой blog/templates/blog/post_detail.html и добавь следующую строку:
так, чтобы шаблон выглядел следующим образом:
В файле blog/urls.py добавь:
Мы будем использовать повторно шаблон blog/templates/blog/post_edit.html , так что осталось лишь отсутствующее представление.
Давай откроем файл blog/views.py и добавим в самый конец следующее:
Выглядит практически идентично представлению post_new , верно? Но не совсем. Во-первых, мы передаём параметр pk из URL-адреса. Кроме того, мы получаем модель Post для редактирования при помощи get_object_or_404(Post, pk=pk) и передаём экземпляр post в качестве instance форме и при сохранении…
… и когда мы открываем форму для редактирования:
Хорошо, давай удостоверимся, что всё работает! Перейди на страницу post_detail . Ты должна увидеть кнопку редактирования в правом верхнем углу:
Когда ты её нажмёшь, то увидишь форму с выбранной записью:
Поменяй заголовок и текст, а затем сохрани запись!
Поздравляем! Твое приложение становится всё более сложным!
Если тебе нужно больше информации о формах в Django, обратись к официальной документации: https://docs.djangoproject.com/en/2.0/topics/forms/
Безопасность
Круто иметь возможность создавать новые посты, просто перейдя по ссылке! Однако сейчас кто угодно из посетителей твоего сайта может создать новую запись в блоге, а это, скорее всего, совсем не то, чего бы тебе хотелось. Давай сделаем так, чтобы кнопка показывалась для нас, а не кого-либо ещё.
В файле blog/templates/blog/base.html найди page-header div и тег <a> , который мы добавили ранее. Должно выглядеть примерно так:
Мы добавим сюда ещё один тег <% if %>, чтобы ссылка показывалась только пользователям, вошедшим в админку. То есть пока что — только тебе! Измени тег <a> , чтобы получилось так:
Из-за этого <% if %>ссылка будет отправлена в браузер, только если запрашивающий страницу пользователь вошёл в систему. Это не обезопасит создание новых постов полностью, но для начала и это неплохо. Мы подробнее рассмотрим вопросы безопасности в дополнении к учебнику.
Помнишь иконку редактирования, которую мы добавили на страницу поста? Чтобы посторонние не смогли менять уже созданные посты, нам нужно изменить страничку похожим образом.
Открой файл blog/templates/blog/post_detail.html и найди такую строку:
Замени её на следующее:
Поскольку ты авторизована, никаких изменений после обновления страницы ты не увидишь. Но попробуй загрузить страницу в другом браузере или в режиме инкогнито, и увидишь, что ссылка не отобразится!
И последнее: публикация!
Теперь давай посмотрим, как это будет работать на PythonAnywhere. Пришло время для очередного развёртывания!
- Сначала нам нужно сделать commit и push нового кода в репозиторий GitHub:
- Затем набери в Bash-консоли PythonAnywhere:
(Не забудь подставить вместо свой поддомен на PythonAnywhere без угловых скобок.)
Django, как сделать поля формы необязательными
Предполагая, что вы хотите сделать last_name необязательным, вы можете использовать blank атрибут:
Обратите внимание, что на CharField и TextField вы, вероятно, не хотите устанавливать значение null (см. Этот ответ для обсуждения того, почему), но для других типов полей вам понадобится, или вы не сможете сохранить экземпляры, где необязательные значения опущены.
Вы используете required аргумент, отправленный с False значением:
Если вы хотите разрешить пустые значения в поле даты (например, DateField , TimeField , DateTimeField ) или числовом поле (например, IntegerField , DecimalField , FloatField ), вам нужно использовать оба null=True и blank=True .