.. .. 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 ``