campo moeda (R$)

2,624 views
Skip to first unread message

jeferson

unread,
Aug 14, 2008, 10:12:05 AM8/14/08
to Django Brasil
Pessoal,

Como trato um campo para moeda? Se eu coloco float ele não aceita
virgula, e acredito que decimal não seja aconselhavel.

Como faço para ter um campo moeda no meu form que aceita a formatação
do Brasil?

Jader Rubini

unread,
Aug 14, 2008, 10:30:10 AM8/14/08
to django...@googlegroups.com
Decimal é aconselhável desde que você comunique isso a seu usuário. ;)

---------------------
Jader Rubini
Desenvolvedor Web / Publicitário
jader...@gmail.com


> -----Mensagem original-----
> De: django...@googlegroups.com [mailto:django...@googlegroups.com]
> Em nome de jeferson
> Enviada em: quinta-feira, 14 de agosto de 2008 11:12
> Para: Django Brasil
> Assunto: [django-brasil] campo moeda (R$)

Michel Thadeu Sabchuk

unread,
Aug 14, 2008, 12:53:36 PM8/14/08
to Django Brasil
> Como trato um campo para moeda? Se eu coloco float ele não aceita
> virgula, e acredito que decimal não seja aconselhavel.

Eu usaria o decimal e faria um custom field. Me deparei recentemente
com isso, eu uso o DecimalField para guardar valores monetários, não
uso a administração para o cadastro, tenho uma interface alternativa,
por isso, uso o forms.CharField validando para um valor decimal
(instância de decimal.Decimal). Como eu tinha começado errado, fiquei
com preguiça de fazer um custom field para essa validação mas hoje
faria diferente ;)

Algumas observações sobre a classe decimal.Decimal, sempre que puder,
procure usar o decimal.Decimal, mesmo em suas contantes, ao converter
um valor para decimal, passe uma representação de string para seu
construtor, ele não aceita converter float para decimal sem antes vc
converter para uma string.

Abraço!

Arthur Furlan

unread,
Aug 14, 2008, 5:09:33 PM8/14/08
to django...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Michel Thadeu Sabchuk wrote:
>> Como trato um campo para moeda? Se eu coloco float ele não aceita
>> virgula, e acredito que decimal não seja aconselhavel.
>
> Eu usaria o decimal e faria um custom field. Me deparei recentemente
> com isso, eu uso o DecimalField para guardar valores monetários, não
> uso a administração para o cadastro, tenho uma interface alternativa,
> por isso, uso o forms.CharField validando para um valor decimal
> (instância de decimal.Decimal). Como eu tinha começado errado, fiquei
> com preguiça de fazer um custom field para essa validação mas hoje
> faria diferente ;)

Eu estou utilizando algo bem parecido, no banco de dados eu utilizo o
campo do tipo Decimal o no formulário, utilizo RegexField:

price = forms.RegexField(regex='^[0-9]{1,10},[0-9]{2}$')

A conversão de string para decimal eu faço hora de salvar o dado.

> Algumas observações sobre a classe decimal.Decimal, sempre que puder,
> procure usar o decimal.Decimal, mesmo em suas contantes, ao converter
> um valor para decimal, passe uma representação de string para seu
> construtor, ele não aceita converter float para decimal sem antes vc
> converter para uma string.

Legal isso, vou passar a fazer isso! Antes eu tratava esses campos como
float mesmo. :)


- --
Atenciosamente,

Arthur Furlan
arthur...@gmail.com

>
> Abraço!
> >
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFIpJ8NHiIxAB175NwRAuoJAKC7jY2zxovSUWVnkFldZD0kgqdxHACdHf8X
inaUXFtVc07OgItT/iUm8dQ=
=ZpGV
-----END PGP SIGNATURE-----

Michel Thadeu Sabchuk

unread,
Aug 15, 2008, 8:47:16 AM8/15/08
to Django Brasil
Olá,

> > Algumas observações sobre a classe decimal.Decimal, sempre que puder,
> > procure usar o decimal.Decimal, mesmo em suas contantes, ao converter
> > um valor para decimal, passe uma representação de string para seu
> > construtor, ele não aceita converter float para decimal sem antes vc
> > converter para uma string.
>
> Legal isso, vou passar a fazer isso! Antes eu tratava esses campos como
> float mesmo. :)

Na verdade recomenda-se o decimal.Decimal por causa de precisão que o
float não garante.

Abraço!

jeferson

unread,
Aug 16, 2008, 9:01:21 AM8/16/08
to Django Brasil
Olá Arthur,

Como eu faço a conversão na hora de salvar? Eu uso o Admin, mas sei
que posso alterar o save. Como faria essa conversão de String para
Decimal na hora de salvar?
> arthur.fur...@gmail.com
>
>
>
> > Abraço!
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.6 (GNU/Linux)
> Comment: Using GnuPG with Mozilla -http://enigmail.mozdev.org

Arthur Furlan

unread,
Aug 16, 2008, 4:45:07 PM8/16/08
to django...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

jeferson wrote:
> Olá Arthur,

Olá Jeferson.

> Como eu faço a conversão na hora de salvar? Eu uso o Admin, mas sei
> que posso alterar o save. Como faria essa conversão de String para
> Decimal na hora de salvar?

Como o seu campo já passou pela validação da regex, então você tem
certeza de que ele está no formato "[0-9]{1,10},[0-9]{2}" e portanto
você pode fazer a conversão da seguinte forma:

from decimal import Decimal
price = Decimal(self.cleaned_data['price'].replace(',', '.'))

- --
Atenciosamente,

Arthur Furlan
arthur...@gmail.com

>
> On 14 ago, 18:09, Arthur Furlan <arthur.fur...@gmail.com> wrote:
> Michel Thadeu Sabchuk wrote:
>>>>> Como trato um campo para moeda? Se eu coloco float ele não aceita
>>>>> virgula, e acredito que decimal não seja aconselhavel.
>>>> Eu usaria o decimal e faria um custom field. Me deparei recentemente
>>>> com isso, eu uso o DecimalField para guardar valores monetários, não
>>>> uso a administração para o cadastro, tenho uma interface alternativa,
>>>> por isso, uso o forms.CharField validando para um valor decimal
>>>> (instância de decimal.Decimal). Como eu tinha começado errado, fiquei
>>>> com preguiça de fazer um custom field para essa validação mas hoje
>>>> faria diferente ;)
> Eu estou utilizando algo bem parecido, no banco de dados eu utilizo o
> campo do tipo Decimal o no formulário, utilizo RegexField:
>
> price = forms.RegexField(regex='^[0-9]{1,10},[0-9]{2}$')
>
> A conversão de string para decimal eu faço hora de salvar o dado.
>
>>>> Algumas observações sobre a classe decimal.Decimal, sempre que puder,
>>>> procure usar o decimal.Decimal, mesmo em suas contantes, ao converter
>>>> um valor para decimal, passe uma representação de string para seu
>>>> construtor, ele não aceita converter float para decimal sem antes vc
>>>> converter para uma string.
> Legal isso, vou passar a fazer isso! Antes eu tratava esses campos como
> float mesmo. :)
>
>

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFIpzxTHiIxAB175NwRApZKAKCkLHKvt5inwSKi2rUu1QLpwoEYfgCeIhf6
bVqpPUB248jtB018MzNtBYg=
=utXF
-----END PGP SIGNATURE-----

jeferson

unread,
Aug 16, 2008, 7:16:36 PM8/16/08
to Django Brasil
Olá Arthur,

Fiz o que me aconselhou e agora o campo aceita que eu insira uma
vírgula, salvando normalmente o valor com PONTO no banco. Gostaria de
saber o que fazer para que seja salvo com vírgula, não com ponto. Caso
não seja possível, como faço para substituir esse ponto no campo
salvo?

Ps.: Fiz da seguinte forma:

O campo valor no models.Model está como DecimalField(). Como estou
usando o admin, fiz um forms.ModelForm para alterar meus campos,
fazendo overridden em alguns, tipo CPF e alterando o formato de outro,
como campos de data (apesar desse ainda me apresentar o formato
americano mas validar apenas no formato d/m/y - estranho, mas ainda
estou vendo como resolver). O campo valor no forms.ModelForm foi
atribuído como regex, como sugeriu. Ainda no meu forms.ModelForm fiz
uma função que converte o valor do campo regex para decimal,
retornando 'valor'.

Essa forma de trabalhar com o campo está certa? Coloco no models.Model
o campo no tipo DecimalField mesmo?

Grato desde já pela atenção!

Jéferson Brito


On 16 ago, 17:45, Arthur Furlan <arthur.fur...@gmail.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> jeferson wrote:
> > Olá Arthur,
>
> Olá Jeferson.
>
> > Como eu faço a conversão na hora de salvar? Eu uso o Admin, mas sei
> > que posso alterar o save. Como faria essa conversão de String para
> > Decimal na hora de salvar?
>
> Como o seu campo já passou pela validação da regex, então você tem
> certeza de que ele está no formato "[0-9]{1,10},[0-9]{2}" e portanto
> você pode fazer a conversão da seguinte forma:
>
> from decimal import Decimal
> price = Decimal(self.cleaned_data['price'].replace(',', '.'))
>
> - --
> Atenciosamente,
>
> Arthur Furlan
> arthur.fur...@gmail.com
>
>
>
>
>
> > On 14 ago, 18:09, Arthur Furlan <arthur.fur...@gmail.com> wrote:
> > Michel Thadeu Sabchuk wrote:
> >>>>> Como trato um campo para moeda? Se eu coloco float ele não aceita
> >>>>> virgula, e acredito que decimal não seja aconselhavel.
> >>>> Eu usaria o decimal e faria um custom field. Me deparei recentemente
> >>>> com isso, eu uso o DecimalField para guardar valores monetários, não
> >>>> uso a administração para o cadastro, tenho uma interface alternativa,
> >>>> por isso, uso o forms.CharField validando para um valor decimal
> >>>> (instância de decimal.Decimal). Como eu tinha começado errado, fiquei
> >>>> com preguiça de fazer um custom field para essa validação mas hoje
> >>>> faria diferente ;)
> > Eu estou utilizando algo bem parecido, no banco de dados eu utilizo o
> > campo do tipo Decimal o no formulário, utilizo RegexField:
>
> > price = forms.RegexField(regex='^[0-9]{1,10},[0-9]{2}$')
>
> > A conversão de string para decimal eu faço hora de salvar o dado.
>
> >>>> Algumas observações sobre a classe decimal.Decimal, sempre que puder,
> >>>> procure usar o decimal.Decimal, mesmo em suas contantes, ao converter
> >>>> um valor para decimal, passe uma representação de string para seu
> >>>> construtor, ele não aceita converter float para decimal sem antes vc
> >>>> converter para uma string.
> > Legal isso, vou passar a fazer isso! Antes eu tratava esses campos como
> > float mesmo. :)
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.6 (GNU/Linux)
> Comment: Using GnuPG with Mozilla -http://enigmail.mozdev.org

jeferson

unread,
Aug 16, 2008, 7:44:02 PM8/16/08
to Django Brasil
Em complemento a pergunta acima, usando o regex e a conversão consigo
inserir a vírgula para validar o campo (deve-se digitar a vírgula para
continuar), mas, além de salvar com ponto no banco, quando volto a
editar os registro, como o valor está com o ponto novamente, não
consigo gravar sem ter que colocar vírgula novamente. Devo fazer a
substituição do ponto por vírgula toda vez que entrar na edição, com,
por exemplo, Javascript?

Arthur Furlan

unread,
Aug 16, 2008, 10:13:16 PM8/16/08
to django...@googlegroups.com
On 8/16/08, jeferson <nas...@gmail.com> wrote:
> Olá Arthur,

Olá Jeferson,

> Fiz o que me aconselhou e agora o campo aceita que eu insira uma
> vírgula, salvando normalmente o valor com PONTO no banco. Gostaria de
> saber o que fazer para que seja salvo com vírgula, não com ponto.

Nesse caso somente utilizando campos do tipo models.CharField, porém
eu acho mais aconselhável utilizar campos do tipo models.DecimalField
porque na realidade você lidando com valores decimais. Ainda lhe resta
a opção de alterar o locale do seu banco de dados, mas isso eu acho
menos aconselhável ainda. :)

> Caso não seja possível, como faço para substituir esse ponto no campo
> salvo?

Quando você quiser resgatar esse valor, você pode substituir o ponto
da seguinte forma:

str(seu_objeto.seu_campo_decimal).replace('.', ',')

> O campo valor no models.Model está como DecimalField(). Como estou
> usando o admin, fiz um forms.ModelForm para alterar meus campos,
> fazendo overridden em alguns, tipo CPF e alterando o formato de outro,
> como campos de data (apesar desse ainda me apresentar o formato
> americano mas validar apenas no formato d/m/y - estranho, mas ainda
> estou vendo como resolver). O campo valor no forms.ModelForm foi
> atribuído como regex, como sugeriu. Ainda no meu forms.ModelForm fiz
> uma função que converte o valor do campo regex para decimal,
> retornando 'valor'.
>
> Essa forma de trabalhar com o campo está certa? Coloco no models.Model
> o campo no tipo DecimalField mesmo?

Se isso está certo ou não, realmente não sei... Acredito que o mais
correto fosse criar um custom field para lidar com valores monetários
do nosso país. Quando tive que trabalhar com valores desse tipo,
acabei resolvendo com RegexField, na época procurei alguma solução
mais correta/padronizada/etc. mas não encontrei nada.


--
Atenciosamente,

Arthur Furlan
arthur...@gmail.com

>

Vinicius Brandao

unread,
Aug 16, 2008, 10:31:09 PM8/16/08
to django...@googlegroups.com
Se alguém tem esse custom field poderia disponibilizar para facilitar a vida? Afinal, não tem por que reinventar a roda né?!

Falo isso por que eu acho que a plugabilidade é um dos diferenciais do django.

2008/8/16 Arthur Furlan <arthur...@gmail.com>
Message has been deleted

jeferson

unread,
Aug 17, 2008, 1:27:18 AM8/17/08
to Django Brasil
Arthur,

Bom, então continuo de RegexField! :)

Quanto ao str(meu_objeto.meu_campo_decimal).replace('.', ','), tinha
visto algo semelhante, mas, onde coloco no fonte?

Grato!

Jéferson Brito

On 16 ago, 23:13, "Arthur Furlan" <arthur.fur...@gmail.com> wrote:
> arthur.fur...@gmail.com

Marinho Brandao

unread,
Aug 19, 2008, 7:51:57 AM8/19/08
to django...@googlegroups.com
Olá Jeferson,

bom, contem eu consegui tirar um tempinho pra dar uma olhada nisso.

o resumo é que o Django não suporta formatação de valores
decimais/flutuantes de forma elegante, e a explicação é que isso não é
simples quanto parece. Quando os desenvolvedores constróem esse tipo
de funcionalidade, algumas preocupações são necessárias e nesse caso a
questão da internacionalização é o ponto que dificulta, pois é preciso
criar esse recurso de forma que você possa configurar uma formatação
para cada idioma/país.

a minha recomendação:

- use DecimalField (como o Jader citou lá em cima, é recomendável
usa-lo para valores com casas decimais fixas).
- para a exibição de valores em listagens, crie campos calculados e
retorne com a formatação já indicada nos e-mails anteriores
- para a exibição de valores em templates próprios, use o template
filter floatformat
- para a edição, declare um ModelForm proprio no ModelAdmin (atributo
form) e nesse ModelForm você modifica os campos de valor para o do
snippet em [1]

também não é muito difícil criar algumas classes extendidas pra
ajustar isso no Django (exemplo: criar um ModelAdmin intermediario que
faça esse tratamento automaticamente e criar os templates
"admin/change_view.html" e "admin/change_list.html" também para fazer
tratamentos), mas sabendo que você é iniciante, creio que o melhor é
vc continuar o trabalho e mexer com isso assim que se sentir
confortável)

outras URLs relacionadas ao assunto: [3] e [4]

[1] http://www.djangosnippets.org/snippets/176/
[2] http://www.djangoproject.com/documentation/templates/#floatformat
[3] http://code.djangoproject.com/ticket/2203
[4] http://www.satchmoproject.com/trac/browser/trunk/satchmo/shop/templatetags/currency_filter.py?rev=195

2008/8/17 jeferson <nas...@gmail.com>:
--
Marinho Brandão (José Mário)
http://marinho.webdoisonline.com/
Reply all
Reply to author
Forward
0 new messages