..
.. META INFORMATION OF TRANSLATION
..
.. $TranslationStatus: Done, waiting for revision $
.. $OriginalRevision: 11332 $
.. $TranslationAuthors: Robson Mendonça $
..
.. INFO OF THIS FILE (DO NOT EDIT! UPDATED BY SUBVERSION)
..
.. $HeadURL$
.. $LastChangedRevision$
.. $LastChangedBy$
.. $LastChangedDate$
..
====================
A API de formulários
====================
.. currentmodule:: django.forms
.. admonition:: Sobre este documento
Este documento cobre os detalhes arenosos da API de formulário do Django.
Você deve ler a :doc:`introdução ao trabalho com formulários
` primeiro.
.. _ref-forms-api-bound-unbound:
Bound e unbound formulários
---------------------------
Uma instância de :class:`Form`, pode ser ambos, **bound** para um conjunto de
dados, ou **unbound**.
* Se ela for **bound** para um conjunto de dados, ela será capaz de validar
estes dados renderizando o formulário como um HTML com os dados exibidos
dentro do HTML.
* Se ela for **unbound** ela não fará validação (pois não há dados para
validar!), mas ela ainda poderá renderizar o formulário em branco em HTML.
Para criar uma instância :class:`Form`, simplesmente instancie a classe::
>>> f = ContactForm()
Para embutir dados no formulário, passe um dicionário como o primeiro parâmetro
para o construtor da sua classe :class:`Form`::
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': 'foo@example.com',
... 'cc_myself': True}
>>> f = ContactForm(data)
No dicionário, as chaves são os nomes dos campos, que correspondem aos
atributos na sua classe :class:`Form`. Os valores são os ados que você está
tentando validar. Estes normalmente serão strings, mas não há exigências para
sejam strings. o tipo de dado que você passa depende do :class:`Field`, como
veremos em breve.
.. attribute:: Form.is_bound
Se você precisa distinguir entre instâncias formulários bound e unbound em tempo
de execução, verifique o valor do atributo :attr:`~Form.is_bound`::
>>> f = ContactForm()
>>> f.is_bound
False
>>> f = ContactForm({'subject': 'hello'})
>>> f.is_bound
True
Note que passando um dicionário vazio você cria um formulário *bound* sem
dados::
>>> f = ContactForm({})
>>> f.is_bound
True
Se você tem uma instância :class:`Form` e deseja mudar os dados de alguma forma,
ou se você quer vincular uma instância unbound para algum dado, crie outra
instância :class:`Form`. Não há formas de mudar os dados numa instância
:class:`Form`. Uma vez que uma instância de :class:`Form` foi criada, você deve
considerar seus dados imutável, tendo ela dados ou não.
Usando formulários para validar dados
-------------------------------------
.. method:: Form.is_valid()
A primeira tarefa de um objeto :class:`Form` é validar dados. Com uma instância
de preenchida de um formulário, chame o método :meth:`~Forms.is_valid` para
executar a validação e retornar um booleano designando se ele foi validado::
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': 'foo@example.com',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
True
Vamos tentar com algum dado inválido. Neste caso, ``subject`` esta em branco (um
erro, pois todos os campos são obrigatórios por padrão) e ``sender`` é um
endereço de email inválido::
>>> data = {'subject': '',
... 'message': 'Hi there',
... 'sender': 'invalid e-mail address',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
False
.. attribute:: Form.errors
Acesse o atributo :attr:`~Form.erros` para pegar um dicionários com as mensagens
de erro::
>>> f.errors
{'sender': [u'Enter a valid e-mail address.'], 'subject': [u'This field is required.']}
Neste dicionário, as chaves são nomes de campos, e os valores são listas de
strings Unicode representando as mensagens de erro. As mensagens de erro são
armazenadas na lista porque um campo pode ter mais de uma mensagem de erro.
Você pode acessar :attr:`~Form.errors` sem ter de chamar
:meth:`~Form.is_valid` primeiro. Os dados do formulário estarão validados na
primeira vez que você chamar :meth:`Form.is_valid` ou acessar o
:attr:`~Form.errors`.
As rotinas de validação serão chamadas somente uma vez, indiferente de quantas
vezes você acessar :attr:`~Forms.errors` ou chamar :meth:`~Form.is_valid`. Isso
significa que se a validação tem efeitos de sentido único, estes efeitos somente
serão disparados uma vez.
Comportamento de formulário vazios
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
É sem sentido validar um formulário sem dados, mas, para registro, aqui está
o que acontece com formulários vazios::
>>> f = ContactForm()
>>> f.is_valid()
False
>>> f.errors
{}
Valores iniciais dinâmicos
--------------------------
.. attribute:: Form.initial
Use ``initial`` para declarar valores iniciais de campos de formulários em tempo
de execução. Por exemplo, você pode querer preencher um campo ``username`` com o
nome de usuário da sessão atual.
Para realizar isso, use o argumento ``initial`` de um ``Form``. Este argumento,
se fornecido, deve ser um dicionário mapeando os nomes dos campos com valores
iniciais. Somente inclua os campos que você estiver especificando um valor
inicial; não é necessário incluír todos os campos do seu formulário. Por
exemplo::
>>> f = ContactForm(initial={'subject': 'Hi there!'})
Estes valores são somente mostrados para formulários vazios, e eles não são
usados como valores de recuo se um valor particular não é fornecido.
Note que se um ``Field`` define ``initial`` *e* você inclui ``initial`` quando
instância o ``Form``, então mais tarde ``initial`` terá prioridade. Neste
exemplo, ``initial`` é fornecido a nível de campo e a nível de instância de
formulário, e mais tarde terá prioridade::
>>> class CommentForm(forms.Form):
... name = forms.CharField(initial='class')
... url = forms.URLField()
... comment = forms.CharField()
>>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
>>> print f
Name:
Url:
Comment:
Acessando dados "limpos"
------------------------
Cada ``Field`` numa classe ``Form`` é responsável não somente por validar dados,
mas também por limpá-los -- normalizando-os para um formato consistente. Essa é
funcionalidade legal, pois ela permite dados de um campo particular ser inserido
de diversas formas, sempre resultando numa saída consistente.
Por exemplo, ``DateField`` normaliza a entrada num objeto ``datetime.date`` do
Python. Indiferentemente de você passar a ele uma string no formato
``'1994-07-15'``, um objeto ``datetime.date`` ou um número de outros formatos,
``DateField`` sempre será normalizado para um objeto ``datetime.date`` assim
que ele for validado.
Uma vez que você tenha criado uma instância do ``Form`` com um conjunto de dados
e validado-os, você pode acessar os dados limpos via atributo ``cleaned_data``
do objeto ``Form``::
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': 'foo@example.com',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
.. versionchanged:: 1.0
The ``cleaned_data`` attribute was called ``clean_data`` in earlier releases.
Note que qualquer campo baseado em texto -- como um ``CharField`` ou
``EmailField`` -- sempre limpa a entrada numa string Unicode. Nós iremos cobrir
as implicações da codificação mais tarde nesse documento.
Se seus dados *não* validam, sua instância do ``Form`` não terá um atributo
``cleaned_data``::
>>> data = {'subject': '',
... 'message': 'Hi there',
... 'sender': 'invalid e-mail address',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
False
>>> f.cleaned_data
Traceback (most recent call last):
...
AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
``cleaned_data`` sempre conterá *somente* uma chave para campos definidos no
``Form``, mesmo se você passar um dados extra quando você definir o ``Form``.
Neste exemplo, nós passamos um grupo de campos extras ao construtor do
``ContactForm``, mas o ``cleaned_data`` contém somente os campos do formulário::
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': 'foo@example.com',
... 'cc_myself': True,
... 'extra_field_1': 'foo',
... 'extra_field_2': 'bar',
... 'extra_field_3': 'baz'}
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data # Doesn't contain extra_field_1, etc.
{'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
``cleanded_data`` incluirá uma chave e um valor para *todos* os campos definidos
no ``Form``, mesmo se os dados não incluem um valor por campo, pois isso não é
obrigatório. Neste exemplo, o dicionário de dados não inclui um valor para o
campo ``nick_name``, mas ``cleaned_data`` o inclui, com um valor vazio::
>>> class OptionalPersonForm(Form):
... first_name = CharField()
... last_name = CharField()
... nick_name = CharField(required=False)
>>> data = {'first_name': u'John', 'last_name': u'Lennon'}
>>> f = OptionalPersonForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'}
Neste exemplo acima, o valor ``cleaned_data`` para ``nick_name`` é setado para
uma estring vazia, porque o ``nick_name`` é ``CharField``, e ``CharField``\s
tratam valores vazios como uma string vazia. Cada tipo de campo sabe como seus
valores "brancos" são -- e.g., para ``DateField``, ele é ``None`` ao invés de
uma string vazia. Para detalhes completos sobre cada comportamento de campo
neste caso, veja a nota "Valor vazio" para cada campos na seção "classes
``Field`` embutidas" abaixo.
Você pode escrever código para executar validação para campos de formulário
específicos (baseados nos seus nomes) ou para um formulário como um todo
(considerando combinações de vários campos). Mais informações sobre isso está
em :ref:`ref-forms-validation`.
Mostrando os formulários como HTML
----------------------------------
A segunda tarefa de um objeto ``Form`` é renderizar a si mesmo como HTML. Para
fazê-lo, simplesmente chame ``print``::
>>> f = ContactForm()
>>> print f
Se o formulário está preenchido com dados, a saída HTML incluirá esses dados
apropriadamente. Por exemplo, se um campo é representado por um
````, o dados estará no atributo ``value``. Se um campo é
representado por um ````, quando este HTML incluir
``checked="checked"`` se apropriado::
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': 'foo@example.com',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> print f
Esta saída padrão é um tabela HTML com duas colunas, com um ``
`` para cada
campo: Note o seguinte:
* Para flexibilidade, a saída *não* incluí as tags ``
`` e
``
``, nem incluí as tags ```` ou um
````. É seu trabalho fazer isso.
* Cada tipo de campo tem uma representação padrão do HTML. ``CharField`` e
``EmailField`` são representado por um ````. O
``BooleanField`` é representado por um ````. Note
estes são simplesmente padrões sensiveis; você pode especificar qual HTML
usar para um dado campo usando widgets, que nós explanaremos logo.
* O ``nome`` de cada tag HTML é dado diretamente por seu atributo name na
classe ``ContactForm``.
* O texto da label de cada campo -- e.g. ``'Subject:'``, ``'Message:'`` e
``'Cc myself:'`` é gerado a partir do nome do campo convertendo todos os
undersocres em espaços e capitalizando a primeira letra. Novamente,
perceba que estes são meramente padrões sensíveis; você pode também
especificar labels manualmente.
* Cada texto de label é envolvido por uma tag HTML ``