Ticket #13473: ticket13473.patch

File ticket13473.patch, 80.2 KB (added by chronos, 5 years ago)

Diff of work at http://github.com/chronossc/django/tree/ticket13473 against http://github.com/django/django at file upload date. This patch contains changes requested in #13495 about refactoring of localflavor tests.

  • django/conf/locale/pt_BR/LC_MESSAGES/django.po

    diff --git a/django/conf/locale/pt_BR/LC_MESSAGES/django.mo b/django/conf/locale/pt_BR/LC_MESSAGES/django.mo
    index 9ee29fd..f7ab6ca 100644
    Binary files a/django/conf/locale/pt_BR/LC_MESSAGES/django.mo and b/django/conf/locale/pt_BR/LC_MESSAGES/django.mo differ
    diff --git a/django/conf/locale/pt_BR/LC_MESSAGES/django.po b/django/conf/locale/pt_BR/LC_MESSAGES/django.po
    index 6eb8013..97902f0 100644
    a b msgid "" 
    55msgstr ""
    66"Project-Id-Version: Django\n"
    77"Report-Msgid-Bugs-To: Grupo de Localização para o Português <django-l10n-portuguese@googlegroups.com>\n"
    8 "POT-Creation-Date: 2010-03-19 17:38-0300\n"
     8"POT-Creation-Date: 2010-05-26 00:42-0300\n"
    99"PO-Revision-Date: 2010-03-19 17:58-0300\n"
    1010"Last-Translator: Guilherme Gondim <semente@taurinus.org>\n"
    1111"Language-Team: Grupo de Localização para o Português <django-l10n-portuguese@googlegroups.com>\n"
    msgid "English" 
    5959msgstr "Inglês"
    6060
    6161#: conf/global_settings.py:55
     62#, fuzzy
     63msgid "British English"
     64msgstr "Inglês"
     65
     66#: conf/global_settings.py:56
    6267msgid "Spanish"
    6368msgstr "Espanhol"
    6469
    65 #: conf/global_settings.py:56
     70#: conf/global_settings.py:57
    6671msgid "Argentinean Spanish"
    6772msgstr "Espanhol Argentino"
    6873
    69 #: conf/global_settings.py:57
     74#: conf/global_settings.py:58
    7075msgid "Estonian"
    7176msgstr "Estoniano"
    7277
    73 #: conf/global_settings.py:58
     78#: conf/global_settings.py:59
    7479msgid "Basque"
    7580msgstr "Basco"
    7681
    77 #: conf/global_settings.py:59
     82#: conf/global_settings.py:60
    7883msgid "Persian"
    7984msgstr "Persa"
    8085
    81 #: conf/global_settings.py:60
     86#: conf/global_settings.py:61
    8287msgid "Finnish"
    8388msgstr "Finlandês"
    8489
    85 #: conf/global_settings.py:61
     90#: conf/global_settings.py:62
    8691msgid "French"
    8792msgstr "Francês"
    8893
    89 #: conf/global_settings.py:62
     94#: conf/global_settings.py:63
    9095msgid "Frisian"
    9196msgstr "Frísia"
    9297
    93 #: conf/global_settings.py:63
     98#: conf/global_settings.py:64
    9499msgid "Irish"
    95100msgstr "Irlandês"
    96101
    97 #: conf/global_settings.py:64
     102#: conf/global_settings.py:65
    98103msgid "Galician"
    99104msgstr "Galiciano"
    100105
    101 #: conf/global_settings.py:65
     106#: conf/global_settings.py:66
    102107msgid "Hebrew"
    103108msgstr "Hebraico"
    104109
    105 #: conf/global_settings.py:66
     110#: conf/global_settings.py:67
    106111msgid "Hindi"
    107112msgstr "Hindi"
    108113
    109 #: conf/global_settings.py:67
     114#: conf/global_settings.py:68
    110115msgid "Croatian"
    111116msgstr "Croata"
    112117
    113 #: conf/global_settings.py:68
     118#: conf/global_settings.py:69
    114119msgid "Hungarian"
    115120msgstr "Húngaro"
    116121
    117 #: conf/global_settings.py:69
     122#: conf/global_settings.py:70
     123#, fuzzy
     124msgid "Indonesian"
     125msgstr "Macedônio"
     126
     127#: conf/global_settings.py:71
    118128msgid "Icelandic"
    119129msgstr "Islandês"
    120130
    121 #: conf/global_settings.py:70
     131#: conf/global_settings.py:72
    122132msgid "Italian"
    123133msgstr "Italiano"
    124134
    125 #: conf/global_settings.py:71
     135#: conf/global_settings.py:73
    126136msgid "Japanese"
    127137msgstr "Japonês"
    128138
    129 #: conf/global_settings.py:72
     139#: conf/global_settings.py:74
    130140msgid "Georgian"
    131141msgstr "Georgiano"
    132142
    133 #: conf/global_settings.py:73
     143#: conf/global_settings.py:75
    134144msgid "Khmer"
    135145msgstr "Khmer"
    136146
    137 #: conf/global_settings.py:74
     147#: conf/global_settings.py:76
    138148msgid "Kannada"
    139149msgstr "Canarês"
    140150
    141 #: conf/global_settings.py:75
     151#: conf/global_settings.py:77
    142152msgid "Korean"
    143153msgstr "Coreano"
    144154
    145 #: conf/global_settings.py:76
     155#: conf/global_settings.py:78
    146156msgid "Lithuanian"
    147157msgstr "Lituano"
    148158
    149 #: conf/global_settings.py:77
     159#: conf/global_settings.py:79
    150160msgid "Latvian"
    151161msgstr "Letão"
    152162
    153 #: conf/global_settings.py:78
     163#: conf/global_settings.py:80
    154164msgid "Macedonian"
    155165msgstr "Macedônio"
    156166
    157 #: conf/global_settings.py:79
     167#: conf/global_settings.py:81
     168#, fuzzy
     169msgid "Mongolian"
     170msgstr "Monaghan"
     171
     172#: conf/global_settings.py:82
    158173msgid "Dutch"
    159174msgstr "Neerlandês"
    160175
    161 #: conf/global_settings.py:80
     176#: conf/global_settings.py:83
    162177msgid "Norwegian"
    163178msgstr "Norueguês"
    164179
    165 #: conf/global_settings.py:81
     180#: conf/global_settings.py:84
     181#, fuzzy
     182msgid "Norwegian Bokmal"
     183msgstr "Norueguês"
     184
     185#: conf/global_settings.py:85
     186#, fuzzy
     187msgid "Norwegian Nynorsk"
     188msgstr "Norueguês"
     189
     190#: conf/global_settings.py:86
    166191msgid "Polish"
    167192msgstr "Polonês"
    168193
    169 #: conf/global_settings.py:82
     194#: conf/global_settings.py:87
    170195msgid "Portuguese"
    171196msgstr "Português"
    172197
    173 #: conf/global_settings.py:83
     198#: conf/global_settings.py:88
    174199msgid "Brazilian Portuguese"
    175200msgstr "Português Brasileiro"
    176201
    177 #: conf/global_settings.py:84
     202#: conf/global_settings.py:89
    178203msgid "Romanian"
    179204msgstr "Romeno"
    180205
    181 #: conf/global_settings.py:85
     206#: conf/global_settings.py:90
    182207msgid "Russian"
    183208msgstr "Russo"
    184209
    185 #: conf/global_settings.py:86
     210#: conf/global_settings.py:91
    186211msgid "Slovak"
    187212msgstr "Eslovaco"
    188213
    189 #: conf/global_settings.py:87
     214#: conf/global_settings.py:92
    190215msgid "Slovenian"
    191216msgstr "Esloveno"
    192217
    193 #: conf/global_settings.py:88
     218#: conf/global_settings.py:93
    194219msgid "Albanian"
    195220msgstr "Albanesa"
    196221
    197 #: conf/global_settings.py:89
     222#: conf/global_settings.py:94
    198223msgid "Serbian"
    199224msgstr "Sérvio"
    200225
    201 #: conf/global_settings.py:90
     226#: conf/global_settings.py:95
    202227msgid "Serbian Latin"
    203228msgstr "Sérvio Latino"
    204229
    205 #: conf/global_settings.py:91
     230#: conf/global_settings.py:96
    206231msgid "Swedish"
    207232msgstr "Sueco"
    208233
    209 #: conf/global_settings.py:92
     234#: conf/global_settings.py:97
    210235msgid "Tamil"
    211236msgstr "Tâmil"
    212237
    213 #: conf/global_settings.py:93
     238#: conf/global_settings.py:98
    214239msgid "Telugu"
    215240msgstr "Telugu"
    216241
    217 #: conf/global_settings.py:94
     242#: conf/global_settings.py:99
    218243msgid "Thai"
    219244msgstr "Tailandês"
    220245
    221 #: conf/global_settings.py:95
     246#: conf/global_settings.py:100
    222247msgid "Turkish"
    223248msgstr "Turco"
    224249
    225 #: conf/global_settings.py:96
     250#: conf/global_settings.py:101
    226251msgid "Ukrainian"
    227252msgstr "Ucraniano"
    228253
    229 #: conf/global_settings.py:97
     254#: conf/global_settings.py:102
    230255msgid "Vietnamese"
    231256msgstr "Vietnamita"
    232257
    233 #: conf/global_settings.py:98
     258#: conf/global_settings.py:103
    234259msgid "Simplified Chinese"
    235260msgstr "Chinês Simplificado"
    236261
    237 #: conf/global_settings.py:99
     262#: conf/global_settings.py:104
    238263msgid "Traditional Chinese"
    239264msgstr "Chinês Tradicional"
    240265
    241 #: contrib/admin/actions.py:52
     266#: contrib/admin/actions.py:48
    242267#, python-format
    243268msgid "Successfully deleted %(count)d %(items)s."
    244269msgstr "Removido %(count)d %(items)s com sucesso."
    245270
    246 #: contrib/admin/actions.py:59 contrib/admin/options.py:1101
     271#: contrib/admin/actions.py:55 contrib/admin/options.py:1125
    247272msgid "Are you sure?"
    248273msgstr "Tem certeza?"
    249274
    250 #: contrib/admin/actions.py:77
     275#: contrib/admin/actions.py:73
    251276#, python-format
    252277msgid "Delete selected %(verbose_name_plural)s"
    253278msgstr "Remover %(verbose_name_plural)s selecionados"
    msgstr "Este mês" 
    286311msgid "This year"
    287312msgstr "Este ano"
    288313
    289 #: contrib/admin/filterspecs.py:147 forms/widgets.py:470
     314#: contrib/admin/filterspecs.py:147 forms/widgets.py:466
    290315msgid "Yes"
    291316msgstr "Sim"
    292317
    293 #: contrib/admin/filterspecs.py:147 forms/widgets.py:470
     318#: contrib/admin/filterspecs.py:147 forms/widgets.py:466
    294319msgid "No"
    295320msgstr "Não"
    296321
    297 #: contrib/admin/filterspecs.py:154 forms/widgets.py:470
     322#: contrib/admin/filterspecs.py:154 forms/widgets.py:466
    298323msgid "Unknown"
    299324msgstr "Desconhecido"
    300325
    301 #: contrib/admin/helpers.py:19
     326#: contrib/admin/helpers.py:20
    302327msgid "Action:"
    303328msgstr "Ação:"
    304329
    msgstr "entrada de log" 
    330355msgid "log entries"
    331356msgstr "entradas de log"
    332357
    333 #: contrib/admin/options.py:139 contrib/admin/options.py:154
     358#: contrib/admin/options.py:138 contrib/admin/options.py:153
    334359msgid "None"
    335360msgstr "Nenhum"
    336361
    337 #: contrib/admin/options.py:558
     362#: contrib/admin/options.py:559
    338363#, python-format
    339364msgid "Changed %s."
    340365msgstr "Modificado %s."
    341366
    342 #: contrib/admin/options.py:558 contrib/admin/options.py:568
    343 #: contrib/comments/templates/comments/preview.html:16 db/models/base.py:840
    344 #: forms/models.py:556
     367#: contrib/admin/options.py:559 contrib/admin/options.py:569
     368#: contrib/comments/templates/comments/preview.html:16 db/models/base.py:845
     369#: forms/models.py:568
    345370msgid "and"
    346371msgstr "e"
    347372
    348 #: contrib/admin/options.py:563
     373#: contrib/admin/options.py:564
    349374#, python-format
    350375msgid "Added %(name)s \"%(object)s\"."
    351376msgstr "Adicionado %(name)s \"%(object)s\""
    352377
    353 #: contrib/admin/options.py:567
     378#: contrib/admin/options.py:568
    354379#, python-format
    355380msgid "Changed %(list)s for %(name)s \"%(object)s\"."
    356381msgstr "Modificado %(list)s para %(name)s \"%(object)s\"."
    357382
    358 #: contrib/admin/options.py:572
     383#: contrib/admin/options.py:573
    359384#, python-format
    360385msgid "Deleted %(name)s \"%(object)s\"."
    361386msgstr "Deletado %(name)s \"%(object)s\"."
    362387
    363 #: contrib/admin/options.py:576
     388#: contrib/admin/options.py:577
    364389msgid "No fields changed."
    365390msgstr "Nenhum campo modificado."
    366391
    367 #: contrib/admin/options.py:642
     392#: contrib/admin/options.py:643
    368393#, python-format
    369394msgid "The %(name)s \"%(obj)s\" was added successfully."
    370395msgstr "%(name)s \"%(obj)s\": adicionado com sucesso."
    371396
    372 #: contrib/admin/options.py:646 contrib/admin/options.py:679
     397#: contrib/admin/options.py:647 contrib/admin/options.py:680
    373398msgid "You may edit it again below."
    374399msgstr "Você pode editar novamente abaixo."
    375400
    376 #: contrib/admin/options.py:656 contrib/admin/options.py:689
     401#: contrib/admin/options.py:657 contrib/admin/options.py:690
    377402#, python-format
    378403msgid "You may add another %s below."
    379404msgstr "Você pode adicionar outro %s abaixo."
    380405
    381 #: contrib/admin/options.py:677
     406#: contrib/admin/options.py:678
    382407#, python-format
    383408msgid "The %(name)s \"%(obj)s\" was changed successfully."
    384409msgstr "%(name)s \"%(obj)s\": modificado com sucesso."
    385410
    386 #: contrib/admin/options.py:685
     411#: contrib/admin/options.py:686
    387412#, python-format
    388413msgid ""
    389414"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
    msgstr "" 
    391416"%(name)s \"%(obj)s\": adicionado com sucesso. Você pode editar novamente "
    392417"abaixo."
    393418
    394 #: contrib/admin/options.py:743
     419#: contrib/admin/options.py:740 contrib/admin/options.py:997
    395420msgid ""
    396421"Items must be selected in order to perform actions on them. No items have "
    397422"been changed."
    msgstr "" 
    399424"Os itens devem ser selecionados a fim de executar ações sobre eles. Nenhum "
    400425"item foi modificado."
    401426
    402 #: contrib/admin/options.py:761
     427#: contrib/admin/options.py:759
    403428msgid "No action selected."
    404429msgstr "Nenhuma ação selecionada."
    405430
    406 #: contrib/admin/options.py:841
     431#: contrib/admin/options.py:840
    407432#, python-format
    408433msgid "Add %s"
    409434msgstr "Adicionar %s"
    410435
    411 #: contrib/admin/options.py:867 contrib/admin/options.py:1081
     436#: contrib/admin/options.py:866 contrib/admin/options.py:1105
    412437#, python-format
    413438msgid "%(name)s object with primary key %(key)r does not exist."
    414439msgstr "Objeto %(name)s com chave primária %(key)r não existe."
    415440
    416 #: contrib/admin/options.py:932
     441#: contrib/admin/options.py:931
    417442#, python-format
    418443msgid "Change %s"
    419444msgstr "Modificar %s"
    msgstr "Modificar %s" 
    422447msgid "Database error"
    423448msgstr "Erro no banco de dados"
    424449
    425 #: contrib/admin/options.py:1013
     450#: contrib/admin/options.py:1039
    426451#, python-format
    427452msgid "%(count)s %(name)s was changed successfully."
    428453msgid_plural "%(count)s %(name)s were changed successfully."
    429454msgstr[0] "%(count)s %(name)s modificado com sucesso."
    430455msgstr[1] "%(count)s %(name)s modificados com sucesso."
    431456
    432 #: contrib/admin/options.py:1040
    433 #, python-format
    434 msgid "of %(count)d selected"
    435 msgid_plural "of %(count)d selected"
    436 msgstr[0] "de %(count)d selecionado"
    437 msgstr[1] "de %(count)d selecionados"
    438 
    439 #: contrib/admin/options.py:1042
     457#: contrib/admin/options.py:1066
    440458#, python-format
    441459msgid "%(total_count)s selected"
    442460msgid_plural "All %(total_count)s selected"
    443461msgstr[0] "%(total_count)s selecionado"
    444462msgstr[1] "Todos %(total_count)s selecionados"
    445463
    446 #: contrib/admin/options.py:1094
     464#: contrib/admin/options.py:1071
     465#, fuzzy, python-format
     466msgid "0 of %(cnt)s selected"
     467msgstr "de %(count)d selecionado"
     468
     469#: contrib/admin/options.py:1118
    447470#, python-format
    448471msgid "The %(name)s \"%(obj)s\" was deleted successfully."
    449472msgstr "%(name)s \"%(obj)s\": excluído com sucesso."
    450473
    451 #: contrib/admin/options.py:1131
     474#: contrib/admin/options.py:1155
    452475#, python-format
    453476msgid "Change history: %s"
    454477msgstr "Histórico de modificações: %s"
    455478
    456 #: contrib/admin/sites.py:22 contrib/admin/views/decorators.py:14
     479#: contrib/admin/sites.py:18 contrib/admin/views/decorators.py:14
    457480#: contrib/auth/forms.py:81
    458481msgid ""
    459482"Please enter a correct username and password. Note that both fields are case-"
    msgstr "" 
    462485"Por favor, entre com um usuário e senha corretos. Note que ambos os campos "
    463486"diferenciam maiúsculas e minúsculas."
    464487
    465 #: contrib/admin/sites.py:311 contrib/admin/views/decorators.py:40
     488#: contrib/admin/sites.py:307 contrib/admin/views/decorators.py:40
    466489msgid "Please log in again, because your session has expired."
    467490msgstr "Por favor acesse novamente, pois sua sessão expirou."
    468491
    469 #: contrib/admin/sites.py:318 contrib/admin/views/decorators.py:47
     492#: contrib/admin/sites.py:314 contrib/admin/views/decorators.py:47
    470493msgid ""
    471494"Looks like your browser isn't configured to accept cookies. Please enable "
    472495"cookies, reload this page, and try again."
    msgstr "" 
    474497"Parece que seu navegador não está configurado para aceitar cookies. Por "
    475498"favor habilite os cookies, recarregue esta página, e tente novamente."
    476499
    477 #: contrib/admin/sites.py:334 contrib/admin/sites.py:340
     500#: contrib/admin/sites.py:330 contrib/admin/sites.py:336
    478501#: contrib/admin/views/decorators.py:66
    479502msgid "Usernames cannot contain the '@' character."
    480503msgstr "Nomes de usuário não podem conter o caractere '@'."
    481504
    482 #: contrib/admin/sites.py:337 contrib/admin/views/decorators.py:62
     505#: contrib/admin/sites.py:333 contrib/admin/views/decorators.py:62
    483506#, python-format
    484507msgid "Your e-mail address is not your username. Try '%s' instead."
    485508msgstr "Seu endereço de e-mail não é seu nome de usuário. Tente usar '%s'"
    486509
    487 #: contrib/admin/sites.py:393
     510#: contrib/admin/sites.py:389
    488511msgid "Site administration"
    489512msgstr "Administração do Site"
    490513
    491 #: contrib/admin/sites.py:407 contrib/admin/templates/admin/login.html:26
     514#: contrib/admin/sites.py:403 contrib/admin/templates/admin/login.html:26
    492515#: contrib/admin/templates/registration/password_reset_complete.html:14
    493516#: contrib/admin/views/decorators.py:20
    494517msgid "Log in"
    495518msgstr "Acessar"
    496519
    497 #: contrib/admin/sites.py:452
     520#: contrib/admin/sites.py:448
    498521#, python-format
    499522msgid "%s administration"
    500523msgstr "Administração de %s"
    msgstr "Desculpe, mas a página requisitada não pode ser encontrada." 
    534557
    535558#: contrib/admin/templates/admin/500.html:4
    536559#: contrib/admin/templates/admin/app_index.html:8
    537 #: contrib/admin/templates/admin/base.html:54
     560#: contrib/admin/templates/admin/base.html:55
    538561#: contrib/admin/templates/admin/change_form.html:18
    539 #: contrib/admin/templates/admin/change_list.html:39
     562#: contrib/admin/templates/admin/change_list.html:42
    540563#: contrib/admin/templates/admin/delete_confirmation.html:6
    541564#: contrib/admin/templates/admin/delete_selected_confirmation.html:6
    542565#: contrib/admin/templates/admin/invalid_setup.html:4
    msgstr "Executar ação selecionada" 
    581604msgid "Go"
    582605msgstr "Ir"
    583606
    584 #: contrib/admin/templates/admin/actions.html:10
     607#: contrib/admin/templates/admin/actions.html:11
    585608msgid "Click here to select the objects across all pages"
    586609msgstr "Clique aqui para selecionar os objetos de todas as páginas"
    587610
    588 #: contrib/admin/templates/admin/actions.html:10
     611#: contrib/admin/templates/admin/actions.html:11
    589612#, python-format
    590613msgid "Select all %(total_count)s %(module_name)s"
    591614msgstr "Selecionar todos %(total_count)s %(module_name)s"
    592615
    593 #: contrib/admin/templates/admin/actions.html:12
     616#: contrib/admin/templates/admin/actions.html:13
    594617msgid "Clear selection"
    595618msgstr "Limpar seleção"
    596619
    msgstr "Limpar seleção" 
    600623msgid "%(name)s"
    601624msgstr "%(name)s"
    602625
    603 #: contrib/admin/templates/admin/base.html:27
     626#: contrib/admin/templates/admin/base.html:28
    604627msgid "Welcome,"
    605628msgstr "Bem vindo,"
    606629
    607 #: contrib/admin/templates/admin/base.html:32
     630#: contrib/admin/templates/admin/base.html:33
    608631#: contrib/admin/templates/registration/password_change_done.html:3
    609632#: contrib/admin/templates/registration/password_change_form.html:4
    610633#: contrib/admindocs/templates/admin_doc/bookmarklets.html:3
    611634msgid "Documentation"
    612635msgstr "Documentação"
    613636
    614 #: contrib/admin/templates/admin/base.html:40
     637#: contrib/admin/templates/admin/base.html:41
    615638#: contrib/admin/templates/admin/auth/user/change_password.html:15
    616639#: contrib/admin/templates/admin/auth/user/change_password.html:48
    617640#: contrib/admin/templates/registration/password_change_done.html:3
    msgstr "Documentação" 
    619642msgid "Change password"
    620643msgstr "Alterar senha"
    621644
    622 #: contrib/admin/templates/admin/base.html:47
     645#: contrib/admin/templates/admin/base.html:48
    623646#: contrib/admin/templates/registration/password_change_done.html:3
    624647#: contrib/admin/templates/registration/password_change_form.html:4
    625648msgid "Log out"
    msgid "View on site" 
    650673msgstr "Ver no site"
    651674
    652675#: contrib/admin/templates/admin/change_form.html:39
    653 #: contrib/admin/templates/admin/change_list.html:68
     676#: contrib/admin/templates/admin/change_list.html:71
    654677#: contrib/admin/templates/admin/auth/user/change_password.html:24
    655678#: contrib/admin/templates/registration/password_change_form.html:15
    656679msgid "Please correct the error below."
    msgid_plural "Please correct the errors below." 
    658681msgstr[0] "Por favor, corrija o erro abaixo."
    659682msgstr[1] "Por favor, corrija os erros abaixo."
    660683
    661 #: contrib/admin/templates/admin/change_list.html:60
     684#: contrib/admin/templates/admin/change_list.html:63
    662685#, python-format
    663686msgid "Add %(name)s"
    664687msgstr "Adicionar %(name)s"
    665688
    666 #: contrib/admin/templates/admin/change_list.html:79
     689#: contrib/admin/templates/admin/change_list.html:82
    667690msgid "Filter"
    668691msgstr "Filtro"
    669692
    670693#: contrib/admin/templates/admin/delete_confirmation.html:10
    671 #: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py:297
     694#: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py:302
    672695msgid "Delete"
    673696msgstr "Apagar"
    674697
    msgstr "Senha (novamente)" 
    859882msgid "Enter the same password as above, for verification."
    860883msgstr "Informe a mesma senha digitada acima, para verificação."
    861884
    862 #: contrib/admin/templates/admin/edit_inline/stacked.html:53
    863 #: contrib/admin/templates/admin/edit_inline/tabular.html:99
     885#: contrib/admin/templates/admin/edit_inline/stacked.html:64
     886#: contrib/admin/templates/admin/edit_inline/tabular.html:110
    864887#, python-format
    865888msgid "Add another %(verbose_name)s"
    866889msgstr "Adicionar outro %(verbose_name)s"
    867890
    868 #: contrib/admin/templates/admin/edit_inline/stacked.html:56
    869 #: contrib/admin/templates/admin/edit_inline/tabular.html:102
     891#: contrib/admin/templates/admin/edit_inline/stacked.html:67
     892#: contrib/admin/templates/admin/edit_inline/tabular.html:113
    870893#: contrib/comments/templates/comments/delete.html:12
    871894msgid "Remove"
    872895msgstr "Remover"
    msgstr "Endereço de e-mail:" 
    10311054msgid "Reset my password"
    10321055msgstr "Reinicializar minha senha"
    10331056
    1034 #: contrib/admin/templatetags/admin_list.py:240
     1057#: contrib/admin/templatetags/admin_list.py:257
    10351058msgid "All dates"
    10361059msgstr "Todas as datas"
    10371060
    1038 #: contrib/admin/views/main.py:70
     1061#: contrib/admin/views/main.py:65
    10391062#, python-format
    10401063msgid "Select %s"
    10411064msgstr "Selecione %s"
    10421065
    1043 #: contrib/admin/views/main.py:70
     1066#: contrib/admin/views/main.py:65
    10441067#, python-format
    10451068msgid "Select %s to change"
    10461069msgstr "Selecione %s para modificar"
    msgstr "Usuário" 
    12101233
    12111234#: contrib/auth/forms.py:15 contrib/auth/forms.py:49
    12121235msgid "Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."
    1213 msgstr "Obrigatório. 30 caracteres ou menos. Somente letras, dígitos e @/./+/-/_."
     1236msgstr ""
     1237"Obrigatório. 30 caracteres ou menos. Somente letras, dígitos e @/./+/-/_."
    12141238
    12151239#: contrib/auth/forms.py:16 contrib/auth/forms.py:50
    12161240msgid "This value may contain only letters, numbers and @/./+/-/_ characters."
    1217 msgstr "Este valor deve conter apenas letras, números e os caracteres @/./+/-/_."
     1241msgstr ""
     1242"Este valor deve conter apenas letras, números e os caracteres @/./+/-/_."
    12181243
    12191244#: contrib/auth/forms.py:18
    12201245msgid "Password confirmation"
    msgstr "usuário" 
    12991324#: contrib/auth/models.py:196
    13001325msgid ""
    13011326"Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"
    1302 msgstr "Obrigatório. 30 caracteres ou menos. Letras, números e os caracteres @/./+/-/_"
     1327msgstr ""
     1328"Obrigatório. 30 caracteres ou menos. Letras, números e os caracteres @/./+/-/"
     1329"_"
    13031330
    13041331#: contrib/auth/models.py:197
    13051332msgid "first name"
    msgstr "mensagem" 
    13931420msgid "Logged out"
    13941421msgstr "Sessão encerrada"
    13951422
    1396 #: contrib/auth/management/commands/createsuperuser.py:23
    1397 #: core/validators.py:120 forms/fields.py:416
     1423#: contrib/auth/management/commands/createsuperuser.py:24
     1424#: core/validators.py:120 forms/fields.py:427
    13981425msgid "Enter a valid e-mail address."
    13991426msgstr "Informe um endereço de email válido."
    14001427
    msgid "Email address" 
    14621489msgstr "Endereço de e-mail"
    14631490
    14641491#: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8
    1465 #: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1121
     1492#: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1101
    14661493msgid "URL"
    14671494msgstr "URL"
    14681495
    msgstr "comentário" 
    15131540msgid "date/time submitted"
    15141541msgstr "data/hora de envio"
    15151542
    1516 #: contrib/comments/models.py:60 db/models/fields/__init__.py:916
     1543#: contrib/comments/models.py:60 db/models/fields/__init__.py:896
    15171544msgid "IP address"
    15181545msgstr "Endereço IP"
    15191546
    msgstr "" 
    17591786msgid "The base GIS field -- maps to the OpenGIS Specification Geometry type."
    17601787msgstr ""
    17611788
    1762 #: contrib/gis/db/models/fields.py:269
     1789#: contrib/gis/db/models/fields.py:270
    17631790msgid "Point"
    17641791msgstr "Ponto"
    17651792
    1766 #: contrib/gis/db/models/fields.py:273
     1793#: contrib/gis/db/models/fields.py:274
    17671794msgid "Line string"
    17681795msgstr "Linha string"
    17691796
    1770 #: contrib/gis/db/models/fields.py:277
     1797#: contrib/gis/db/models/fields.py:278
    17711798msgid "Polygon"
    17721799msgstr "Polígono"
    17731800
    1774 #: contrib/gis/db/models/fields.py:281
     1801#: contrib/gis/db/models/fields.py:282
    17751802msgid "Multi-point"
    17761803msgstr "Multiponto"
    17771804
    1778 #: contrib/gis/db/models/fields.py:285
     1805#: contrib/gis/db/models/fields.py:286
    17791806msgid "Multi-line string"
    17801807msgstr "Multilinha string"
    17811808
    1782 #: contrib/gis/db/models/fields.py:289
     1809#: contrib/gis/db/models/fields.py:290
    17831810msgid "Multi polygon"
    17841811msgstr "Multipolígono"
    17851812
    1786 #: contrib/gis/db/models/fields.py:293
     1813#: contrib/gis/db/models/fields.py:294
    17871814msgid "Geometry collection"
    17881815msgstr "Coleção geométrica"
    17891816
    msgstr "ontem" 
    18961923msgid "Enter a postal code in the format NNNN or ANNNNAAA."
    18971924msgstr "Informe um código postal no formato NNNN ou ANNNNAAA."
    18981925
    1899 #: contrib/localflavor/ar/forms.py:50 contrib/localflavor/br/forms.py:97
    1900 #: contrib/localflavor/br/forms.py:136 contrib/localflavor/pe/forms.py:24
    1901 #: contrib/localflavor/pe/forms.py:52
     1926#: contrib/localflavor/ar/forms.py:50 contrib/localflavor/br/forms.py:88
     1927#: contrib/localflavor/pe/forms.py:24 contrib/localflavor/pe/forms.py:52
    19021928msgid "This field requires only numbers."
    19031929msgstr "Este campo requer somente números."
    19041930
    msgstr "" 
    19641990msgid "Enter a 4 digit post code."
    19651991msgstr "Informe um código postal de 4 dígitos."
    19661992
    1967 #: contrib/localflavor/br/forms.py:22
     1993#: contrib/localflavor/br/br_cpfcnpj.py:34
     1994msgid "Invalid CNPJ number."
     1995msgstr "Número de CNPJ inválido."
     1996
     1997#: contrib/localflavor/br/br_cpfcnpj.py:35
     1998msgid "CNPJ requires at most 14 digits or 18 characters."
     1999msgstr "Este campo requer no máximo 14 dígitos ou 18 caracteres."
     2000
     2001#: contrib/localflavor/br/br_cpfcnpj.py:36
     2002msgid "CNPJ requires only numbers, allow '.', '/' and '-' for long format."
     2003msgstr "Este campo aceita somente números e os caracteres '.', '/' e '-'."
     2004
     2005#: contrib/localflavor/br/br_cpfcnpj.py:201 contrib/localflavor/br/forms.py:86
     2006msgid "Invalid CPF number."
     2007msgstr "Número de CPF inválido."
     2008
     2009#: contrib/localflavor/br/br_cpfcnpj.py:202
     2010msgid "CPF requires at most 11 digits or 14 characters."
     2011msgstr "Este campo requer no máximo 11 dígitos ou 14 caracteres."
     2012
     2013#: contrib/localflavor/br/br_cpfcnpj.py:203
     2014msgid "CPF requires only numbers, allow '.' and '-' for long format."
     2015msgstr "Este campo aceita somente números e os caracteres '.' e '-'."
     2016
     2017#: contrib/localflavor/br/forms.py:18
    19682018msgid "Enter a zip code in the format XXXXX-XXX."
    19692019msgstr "Informe um código postal no formato XXXXX-XXX."
    19702020
    1971 #: contrib/localflavor/br/forms.py:31
     2021#: contrib/localflavor/br/forms.py:27
    19722022msgid "Phone numbers must be in XX-XXXX-XXXX format."
    19732023msgstr "Números de telefone devem estar no formato XX-XXXX-XXXX."
    19742024
    1975 #: contrib/localflavor/br/forms.py:59
     2025#: contrib/localflavor/br/forms.py:55
    19762026msgid ""
    19772027"Select a valid brazilian state. That state is not one of the available "
    19782028"states."
    msgstr "" 
    19802030"Selecione um estado brasileiro válido. O estado escolhido não é um dos "
    19812031"estados disponíveis."
    19822032
    1983 #: contrib/localflavor/br/forms.py:95
    1984 msgid "Invalid CPF number."
    1985 msgstr "Número de CPF inválido."
    1986 
    1987 #: contrib/localflavor/br/forms.py:96
     2033#: contrib/localflavor/br/forms.py:87
    19882034msgid "This field requires at most 11 digits or 14 characters."
    19892035msgstr "Este campo requer no máximo 11 dígitos ou 14 caracteres."
    19902036
    1991 #: contrib/localflavor/br/forms.py:135
    1992 msgid "Invalid CNPJ number."
    1993 msgstr "Número de CNPJ inválido."
    1994 
    1995 #: contrib/localflavor/br/forms.py:137
    1996 msgid "This field requires at least 14 digits"
    1997 msgstr "Este campo requer ao menos 14 dígitos"
    1998 
    19992037#: contrib/localflavor/ca/forms.py:25
    20002038msgid "Enter a postal code in the format XXX XXX."
    20012039msgstr "Informe um código postal no formato XXX XXX."
    msgstr "sites" 
    44524490msgid "Enter a valid value."
    44534491msgstr "Informe um valor válido."
    44544492
    4455 #: core/validators.py:87 forms/fields.py:517
     4493#: core/validators.py:87 forms/fields.py:528
    44564494msgid "Enter a valid URL."
    44574495msgstr "Informe uma URL válida."
    44584496
    4459 #: core/validators.py:89 forms/fields.py:518
     4497#: core/validators.py:89 forms/fields.py:529
    44604498msgid "This URL appears to be a broken link."
    44614499msgstr "A URL %s aparenta ser um link quebrado."
    44624500
    4463 #: core/validators.py:123 forms/fields.py:861
     4501#: core/validators.py:123 forms/fields.py:877
    44644502msgid ""
    44654503"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."
    44664504msgstr ""
    44674505"Insira um \"slug\" válido consistindo de letras, números, sublinhados (_) ou "
    44684506"hífens."
    44694507
    4470 #: core/validators.py:126 forms/fields.py:854
     4508#: core/validators.py:126 forms/fields.py:870
    44714509msgid "Enter a valid IPv4 address."
    44724510msgstr "Informe um endereço IPv4 válido."
    44734511
    4474 #: core/validators.py:129 db/models/fields/__init__.py:598
     4512#: core/validators.py:129 db/models/fields/__init__.py:572
    44754513msgid "Enter only digits separated by commas."
    44764514msgstr "Informe apenas dígitos separados por vírgulas."
    44774515
    msgstr "Informe apenas dígitos separados por vírgulas." 
    44804518msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)."
    44814519msgstr "Certifique-se de que o valor é %(limit_value)s (ele é %(show_value)s)."
    44824520
    4483 #: core/validators.py:153 forms/fields.py:196 forms/fields.py:246
     4521#: core/validators.py:153 forms/fields.py:204 forms/fields.py:256
    44844522#, python-format
    44854523msgid "Ensure this value is less than or equal to %(limit_value)s."
    44864524msgstr "Certifique-se que este valor seja menor ou igual a %(limit_value)s."
    44874525
    4488 #: core/validators.py:158 forms/fields.py:197 forms/fields.py:247
     4526#: core/validators.py:158 forms/fields.py:205 forms/fields.py:257
    44894527#, python-format
    44904528msgid "Ensure this value is greater than or equal to %(limit_value)s."
    44914529msgstr "Certifique-se que este valor seja maior ou igual a %(limit_value)s."
    msgstr "" 
    45084546"Certifique-se de que o valor tenha no máximo %(limit_value)d caracteres (ele "
    45094547"possui %(show_value)d)."
    45104548
    4511 #: db/models/base.py:818
     4549#: db/models/base.py:823
    45124550#, python-format
    45134551msgid "%(field_name)s must be unique for %(date_field)s %(lookup)s."
    45144552msgstr "%(field_name)s deverá ser único para %(date_field)s %(lookup)s."
    45154553
    4516 #: db/models/base.py:833 db/models/base.py:841
     4554#: db/models/base.py:838 db/models/base.py:846
    45174555#, python-format
    45184556msgid "%(model_name)s with this %(field_label)s already exists."
    45194557msgstr "%(model_name)s com este %(field_label)s já existe."
    45204558
    4521 #: db/models/fields/__init__.py:62
     4559#: db/models/fields/__init__.py:63
    45224560#, python-format
    45234561msgid "Value %r is not a valid choice."
    45244562msgstr "O valor %r não é uma escolha válida."
    45254563
    4526 #: db/models/fields/__init__.py:63
     4564#: db/models/fields/__init__.py:64
    45274565msgid "This field cannot be null."
    45284566msgstr "Este campo não pode ser nulo."
    45294567
    4530 #: db/models/fields/__init__.py:64
     4568#: db/models/fields/__init__.py:65
    45314569msgid "This field cannot be blank."
    45324570msgstr "Este campo não pode estar em branco."
    45334571
    4534 #: db/models/fields/__init__.py:69
     4572#: db/models/fields/__init__.py:70
    45354573#, python-format
    45364574msgid "Field of type: %(field_type)s"
    45374575msgstr "Campo do tipo: %(field_type)s"
    45384576
    4539 #: db/models/fields/__init__.py:477 db/models/fields/__init__.py:878
    4540 #: db/models/fields/__init__.py:981 db/models/fields/__init__.py:992
    4541 #: db/models/fields/__init__.py:1019
     4577#: db/models/fields/__init__.py:451 db/models/fields/__init__.py:852
     4578#: db/models/fields/__init__.py:961 db/models/fields/__init__.py:972
     4579#: db/models/fields/__init__.py:999
    45424580msgid "Integer"
    45434581msgstr "Inteiro"
    45444582
    4545 #: db/models/fields/__init__.py:481 db/models/fields/__init__.py:876
     4583#: db/models/fields/__init__.py:455 db/models/fields/__init__.py:850
    45464584msgid "This value must be an integer."
    45474585msgstr "Este valor deve ser um inteiro."
    45484586
    4549 #: db/models/fields/__init__.py:516
     4587#: db/models/fields/__init__.py:490
    45504588msgid "This value must be either True or False."
    45514589msgstr "Este valor deve ser True ou False."
    45524590
    4553 #: db/models/fields/__init__.py:518
     4591#: db/models/fields/__init__.py:492
    45544592msgid "Boolean (Either True or False)"
    45554593msgstr "Booleano (Verdadeiro ou Falso)"
    45564594
    4557 #: db/models/fields/__init__.py:565 db/models/fields/__init__.py:1002
     4595#: db/models/fields/__init__.py:539 db/models/fields/__init__.py:982
    45584596#, python-format
    45594597msgid "String (up to %(max_length)s)"
    45604598msgstr "String (até %(max_length)s)"
    45614599
    4562 #: db/models/fields/__init__.py:593
     4600#: db/models/fields/__init__.py:567
    45634601msgid "Comma-separated integers"
    45644602msgstr "Inteiros separados por vírgula"
    45654603
    4566 #: db/models/fields/__init__.py:607
     4604#: db/models/fields/__init__.py:581
    45674605msgid "Date (without time)"
    45684606msgstr "Data (sem hora)"
    45694607
    4570 #: db/models/fields/__init__.py:611
     4608#: db/models/fields/__init__.py:585
    45714609msgid "Enter a valid date in YYYY-MM-DD format."
    45724610msgstr "Informe uma data válida no formato AAAA-MM-DD."
    45734611
    4574 #: db/models/fields/__init__.py:612
     4612#: db/models/fields/__init__.py:586
    45754613#, python-format
    45764614msgid "Invalid date: %s"
    45774615msgstr "Data inválida: %s"
    45784616
    4579 #: db/models/fields/__init__.py:693
     4617#: db/models/fields/__init__.py:667
    45804618msgid "Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format."
    45814619msgstr ""
    45824620"Informe uma data/hora válida no formato YYYY-MM-DD HH:MM[:ss[.uuuuuu]]."
    45834621
    4584 #: db/models/fields/__init__.py:695
     4622#: db/models/fields/__init__.py:669
    45854623msgid "Date (with time)"
    45864624msgstr "Data e hora"
    45874625
    4588 #: db/models/fields/__init__.py:761
     4626#: db/models/fields/__init__.py:735
    45894627msgid "This value must be a decimal number."
    45904628msgstr "Este valor deve ser um número decimal."
    45914629
    4592 #: db/models/fields/__init__.py:763
     4630#: db/models/fields/__init__.py:737
    45934631msgid "Decimal number"
    45944632msgstr "Número decimal"
    45954633
    4596 #: db/models/fields/__init__.py:818
     4634#: db/models/fields/__init__.py:792
    45974635msgid "E-mail address"
    45984636msgstr "Endereço de e-mail"
    45994637
    4600 #: db/models/fields/__init__.py:825 db/models/fields/files.py:220
     4638#: db/models/fields/__init__.py:799 db/models/fields/files.py:220
    46014639#: db/models/fields/files.py:331
    46024640msgid "File path"
    46034641msgstr "Caminho de arquivo"
    46044642
    4605 #: db/models/fields/__init__.py:848
     4643#: db/models/fields/__init__.py:822
    46064644msgid "This value must be a float."
    46074645msgstr "Este valor deve ser um ponto flutuante."
    46084646
    4609 #: db/models/fields/__init__.py:850
     4647#: db/models/fields/__init__.py:824
    46104648msgid "Floating point number"
    46114649msgstr "Número de ponto flutuante"
    46124650
    4613 #: db/models/fields/__init__.py:903
     4651#: db/models/fields/__init__.py:883
    46144652msgid "Big (8 byte) integer"
    46154653msgstr "Inteiro grande (8 byte)"
    46164654
    4617 #: db/models/fields/__init__.py:932
     4655#: db/models/fields/__init__.py:912
    46184656msgid "This value must be either None, True or False."
    46194657msgstr "Este valor deve ser None, True ou False."
    46204658
    4621 #: db/models/fields/__init__.py:934
     4659#: db/models/fields/__init__.py:914
    46224660msgid "Boolean (Either True, False or None)"
    46234661msgstr "Booleano (Verdadeiro, Falso ou Nada)"
    46244662
    4625 #: db/models/fields/__init__.py:1025
     4663#: db/models/fields/__init__.py:1005
    46264664msgid "Text"
    46274665msgstr "Texto"
    46284666
    4629 #: db/models/fields/__init__.py:1041
     4667#: db/models/fields/__init__.py:1021
    46304668msgid "Time"
    46314669msgstr "Hora"
    46324670
    4633 #: db/models/fields/__init__.py:1045
     4671#: db/models/fields/__init__.py:1025
    46344672msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format."
    46354673msgstr "Informe uma hora válida no formato HH:MM[:ss[.uuuuuu]]."
    46364674
    4637 #: db/models/fields/__init__.py:1129
     4675#: db/models/fields/__init__.py:1109
    46384676msgid "XML text"
    46394677msgstr "Texto XML"
    46404678
    4641 #: db/models/fields/related.py:755
     4679#: db/models/fields/related.py:799
    46424680#, python-format
    46434681msgid "Model %(model)s with pk %(pk)r does not exist."
    46444682msgstr "Model %(model)s com chave primária %(pk)r não existe."
    46454683
    4646 #: db/models/fields/related.py:757
     4684#: db/models/fields/related.py:801
    46474685msgid "Foreign Key (type determined by related field)"
    46484686msgstr "Chave Estrangeira (tipo determinado pelo campo relacionado)"
    46494687
    4650 #: db/models/fields/related.py:879
     4688#: db/models/fields/related.py:918
    46514689msgid "One-to-one relationship"
    46524690msgstr "Relacionamento um-para-um"
    46534691
    4654 #: db/models/fields/related.py:939
     4692#: db/models/fields/related.py:980
    46554693msgid "Many-to-many relationship"
    46564694msgstr "Relacionamento muitos-para-muitos"
    46574695
    4658 #: db/models/fields/related.py:959
     4696#: db/models/fields/related.py:1000
    46594697msgid ""
    46604698"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
    46614699msgstr ""
    46624700"Mantenha pressionado \"Control\" (ou \"Command\" no Mac) para selecionar "
    46634701"mais de uma opção."
    46644702
    4665 #: db/models/fields/related.py:1020
     4703#: db/models/fields/related.py:1061
    46664704#, python-format
    46674705msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
    46684706msgid_plural ""
    msgstr[1] "" 
    46774715msgid "This field is required."
    46784716msgstr "Este campo é obrigatório."
    46794717
    4680 #: forms/fields.py:195
     4718#: forms/fields.py:203
    46814719msgid "Enter a whole number."
    46824720msgstr "Informe um número inteiro."
    46834721
    4684 #: forms/fields.py:225 forms/fields.py:245
     4722#: forms/fields.py:234 forms/fields.py:255
    46854723msgid "Enter a number."
    46864724msgstr "Informe um número."
    46874725
    4688 #: forms/fields.py:248
     4726#: forms/fields.py:258
    46894727#, python-format
    46904728msgid "Ensure that there are no more than %s digits in total."
    46914729msgstr "Certifique-se de que não tenha mais de %s dígitos no total."
    46924730
    4693 #: forms/fields.py:249
     4731#: forms/fields.py:259
    46944732#, python-format
    46954733msgid "Ensure that there are no more than %s decimal places."
    46964734msgstr "Certifique-se de que não tenha mais de %s casa decimais."
    46974735
    4698 #: forms/fields.py:250
     4736#: forms/fields.py:260
    46994737#, python-format
    47004738msgid "Ensure that there are no more than %s digits before the decimal point."
    47014739msgstr ""
    47024740"Certifique-se de que não tenha mais de %s dígitos antes do ponto decimal."
    47034741
    4704 #: forms/fields.py:311 forms/fields.py:826
     4742#: forms/fields.py:322 forms/fields.py:837
    47054743msgid "Enter a valid date."
    47064744msgstr "Informe uma data válida."
    47074745
    4708 #: forms/fields.py:339 forms/fields.py:827
     4746#: forms/fields.py:350 forms/fields.py:838
    47094747msgid "Enter a valid time."
    47104748msgstr "Informe uma hora válida."
    47114749
    4712 #: forms/fields.py:365
     4750#: forms/fields.py:376
    47134751msgid "Enter a valid date/time."
    47144752msgstr "Informe uma data/hora válida."
    47154753
    4716 #: forms/fields.py:423
     4754#: forms/fields.py:434
    47174755msgid "No file was submitted. Check the encoding type on the form."
    47184756msgstr "Nenhum arquivo enviado. Verifique o tipo de codificação do formulário."
    47194757
    4720 #: forms/fields.py:424
     4758#: forms/fields.py:435
    47214759msgid "No file was submitted."
    47224760msgstr "Não foi enviado nenhum arquivo."
    47234761
    4724 #: forms/fields.py:425
     4762#: forms/fields.py:436
    47254763msgid "The submitted file is empty."
    47264764msgstr "O arquivo enviado está vazio."
    47274765
    4728 #: forms/fields.py:426
     4766#: forms/fields.py:437
    47294767#, python-format
    47304768msgid ""
    47314769"Ensure this filename has at most %(max)d characters (it has %(length)d)."
    msgstr "" 
    47334771"Certifique-se de que o arquivo tenha no máximo %(max)d caracteres (ele "
    47344772"possui %(length)d)."
    47354773
    4736 #: forms/fields.py:461
     4774#: forms/fields.py:472
    47374775msgid ""
    47384776"Upload a valid image. The file you uploaded was either not an image or a "
    47394777"corrupted image."
    msgstr "" 
    47414779"Envie uma imagem válida. O arquivo enviado não é uma imagem ou está "
    47424780"corrompido."
    47434781
    4744 #: forms/fields.py:584 forms/fields.py:659
     4782#: forms/fields.py:595 forms/fields.py:670
    47454783#, python-format
    47464784msgid "Select a valid choice. %(value)s is not one of the available choices."
    47474785msgstr "Faça uma escolha válida. %(value)s não está disponível."
    47484786
    4749 #: forms/fields.py:660 forms/fields.py:722 forms/models.py:989
     4787#: forms/fields.py:671 forms/fields.py:733 forms/models.py:1002
    47504788msgid "Enter a list of values."
    47514789msgstr "Informe uma lista de valores."
    47524790
    4753 #: forms/formsets.py:293 forms/formsets.py:295
     4791#: forms/formsets.py:298 forms/formsets.py:300
    47544792msgid "Order"
    47554793msgstr "Ordem"
    47564794
    4757 #: forms/models.py:550
     4795#: forms/models.py:562
    47584796#, python-format
    47594797msgid "Please correct the duplicate data for %(field)s."
    47604798msgstr "Por favor, corrija o valor duplicado para %(field)s."
    47614799
    4762 #: forms/models.py:554
     4800#: forms/models.py:566
    47634801#, python-format
    47644802msgid "Please correct the duplicate data for %(field)s, which must be unique."
    47654803msgstr ""
    47664804"Por favor, corrija o valor duplicado para %(field)s, o qual deve ser único"
    47674805
    4768 #: forms/models.py:560
     4806#: forms/models.py:572
    47694807#, python-format
    47704808msgid ""
    47714809"Please correct the duplicate data for %(field_name)s which must be unique "
    msgstr "" 
    47744812"Por favor corrija os dados duplicados em %(field_name)s que deverá ser único "
    47754813"para o %(lookup)s em %(date_field)s."
    47764814
    4777 #: forms/models.py:568
     4815#: forms/models.py:580
    47784816msgid "Please correct the duplicate values below."
    47794817msgstr "Por favor, corrija os valores duplicados abaixo."
    47804818
    4781 #: forms/models.py:842
     4819#: forms/models.py:855
    47824820msgid "The inline foreign key did not match the parent instance primary key."
    47834821msgstr ""
    47844822"A chave estrangeira no inline não coincide com a chave primária na instância "
    47854823"pai."
    47864824
    4787 #: forms/models.py:908
     4825#: forms/models.py:921
    47884826msgid "Select a valid choice. That choice is not one of the available choices."
    47894827msgstr "Faça uma escolha válida. Sua escolha não é uma das disponíveis."
    47904828
    4791 #: forms/models.py:990
     4829#: forms/models.py:1003
    47924830#, python-format
    47934831msgid "Select a valid choice. %s is not one of the available choices."
    47944832msgstr "Faça uma escolha válida. %s não está disponível."
    47954833
    4796 #: forms/models.py:992
     4834#: forms/models.py:1005
    47974835#, python-format
    47984836msgid "\"%s\" is not a valid value for a primary key."
    47994837msgstr "\"%s\" não é um valor válido para uma chave primária."
    48004838
    4801 #: template/defaultfilters.py:781
     4839#: template/defaultfilters.py:776
    48024840msgid "yes,no,maybe"
    48034841msgstr "sim,não,talvez"
    48044842
    4805 #: template/defaultfilters.py:812
     4843#: template/defaultfilters.py:807
    48064844#, python-format
    48074845msgid "%(size)d byte"
    48084846msgid_plural "%(size)d bytes"
    48094847msgstr[0] "%(size)d byte"
    48104848msgstr[1] "%(size)d bytes"
    48114849
    4812 #: template/defaultfilters.py:814
     4850#: template/defaultfilters.py:809
    48134851#, python-format
    48144852msgid "%.1f KB"
    48154853msgstr "%.1f KB"
    48164854
    4817 #: template/defaultfilters.py:816
     4855#: template/defaultfilters.py:811
    48184856#, python-format
    48194857msgid "%.1f MB"
    48204858msgstr "%.1f MB"
    48214859
    4822 #: template/defaultfilters.py:817
     4860#: template/defaultfilters.py:812
    48234861#, python-format
    48244862msgid "%.1f GB"
    48254863msgstr "%.1f GB"
    msgstr "%(number)d %(type)s" 
    50825120msgid ", %(number)d %(type)s"
    50835121msgstr ", %(number)d %(type)s"
    50845122
    5085 #: utils/translation/trans_real.py:512
     5123#: utils/translation/trans_real.py:519
    50865124msgid "DATE_FORMAT"
    50875125msgstr "j \\de N \\de Y"
    50885126
    5089 #: utils/translation/trans_real.py:513
     5127#: utils/translation/trans_real.py:520
    50905128msgid "DATETIME_FORMAT"
    50915129msgstr "j \\de N \\de Y à\\s H:i"
    50925130
    5093 #: utils/translation/trans_real.py:514
     5131#: utils/translation/trans_real.py:521
    50945132msgid "TIME_FORMAT"
    50955133msgstr "H:i"
    50965134
    5097 #: utils/translation/trans_real.py:535
     5135#: utils/translation/trans_real.py:542
    50985136msgid "YEAR_MONTH_FORMAT"
    50995137msgstr "F \\de Y"
    51005138
    5101 #: utils/translation/trans_real.py:536
     5139#: utils/translation/trans_real.py:543
    51025140msgid "MONTH_DAY_FORMAT"
    51035141msgstr "j \\de F"
    51045142
    msgstr "%(verbose_name)s: atualizado com sucesso." 
    51175155msgid "The %(verbose_name)s was deleted."
    51185156msgstr "%(verbose_name)s: excluído."
    51195157
     5158#~ msgid "This field requires at least 14 digits"
     5159#~ msgstr "Este campo requer ao menos 14 dígitos"
  • new file django/contrib/localflavor/br/br_cpfcnpj.py

    diff --git a/django/contrib/localflavor/br/br_cpfcnpj.py b/django/contrib/localflavor/br/br_cpfcnpj.py
    new file mode 100644
    index 0000000..afdea2c
    - +  
     1# -*- coding: utf-8 -*-
     2
     3import re, math
     4from random import randint
     5from django.db import models
     6from django import forms
     7from django.core.exceptions import ValidationError
     8from django.utils.translation import ugettext as _
     9
     10# -------------------------------------------------
     11# Based in http://www.python.org.br/wiki/VerificadorDeCnpj
     12#
     13class CNPJ(object):
     14    """
     15    This class that represents a CNPJ number.
     16    CNPJ is National Registry of Corporations in Brazil.
     17    A CPF number is compounded by XX.XXX.XXX/XXXX-VD where:
     18      - First 8 digits is company id
     19      - The 4 digits after '/' is number of filial of company
     20      - Last two digits are verification digits
     21
     22    >>> x=CNPJGenerator()
     23    >>> x
     24    '58364950000770'
     25    >>> CNPJ(x)
     26    CNPJ('58364950000770')
     27    >>> CNPJ(x).single
     28    u'58364950000770'
     29    >>> str(CNPJ(x))
     30    '58.364.950/0007-70'
     31    """
     32
     33    error_messages = {
     34        'invalid': _(u"Invalid CNPJ number."),
     35        'max_digits': _(u"CNPJ requires at most 14 digits or 18 characters."),
     36        'digits_only': _(u"CNPJ requires only numbers, allow '.', '/' and '-' for long format."),
     37    }
     38   
     39    def __init__(self, cnpj):
     40       
     41        # transform list or int or long in a string
     42        if type(cnpj) in (int,long):
     43            cnpj = u"%s" % cnpj
     44        if type(cnpj) in (list,tuple):
     45            cnpj= u''.join([str(x) for x in cnpj])
     46
     47        try:
     48            basestring
     49        except:
     50            basestring = (str, unicode)
     51        # only numbers = 14, numbers with '.', '/' and '-' = 18
     52        if len(cnpj) not in (14,18):
     53            raise ValueError(self.error_messages['max_digits'])
     54
     55        if isinstance(cnpj, basestring):
     56            # remove characters
     57            cnpj = cnpj.replace(".", "")
     58            cnpj = cnpj.replace("-", "")
     59            cnpj = cnpj.replace("/", "")
     60
     61            # and check if is digit
     62            if not cnpj.isdigit():
     63                raise ValueError(self.error_messages['digits_only'])
     64
     65        # turn into a list of integers
     66        self.cnpj = map(int, cnpj)
     67
     68        # validate number and validation digits
     69        if not self.is_valid:
     70            raise ValueError(self.error_messages['invalid'])
     71
     72    def __getitem__(self, index):
     73        """
     74        Returns digit at index in CNPJ
     75
     76        >>> a = CNPJ('11222333000181')
     77        >>> a[9] == '0'
     78        True
     79        >>> a[10] == '0'
     80        True
     81        >>> a[9] == 0
     82        False
     83        >>> a[10] == 0
     84        False
     85
     86        """
     87        return str(self.cnpj[index])
     88
     89    def __repr__(self):
     90        return "CNPJ('%s')" % ''.join([str(x) for x in self.cnpj])
     91
     92    def __eq__(self, other):
     93        """
     94        >>> a = CNPJ('11222333000181')
     95        >>> b = CNPJ('11.222.333/0001-81')
     96        >>> c = CNPJ([1, 1, 2, 2, 2, 3, 3, 3, 0, 0, 0, 1, 8, 2])
     97        >>> a == b
     98        True
     99        >>> a != c
     100        True
     101        >>> b != c
     102        True
     103        """
     104        if isinstance(other, CNPJ):
     105            return self.cnpj == other.cnpj
     106        return False
     107
     108    def __unicode__(self):
     109        """
     110        Return CNPJ in long format, with '.', '/' and '.'. For simple format
     111        use CNPJ(...).single property/method
     112
     113        >>> a = CNPJ('11222333000181')
     114        >>> str(a)
     115        u'11.222.333/0001-81'
     116
     117        """
     118        d = ((2, "."), (6, "."), (10, "/"), (15, "-"))
     119        s = map(str, self.cnpj)
     120       
     121        for i, v in d:
     122            s.insert(i, v)
     123       
     124        r = ''.join(s)
     125       
     126        return r
     127   
     128    def __str__(self):
     129        return self.__unicode__()
     130
     131    def __len__(self):
     132        return len(self.cnpj)
     133
     134    @property
     135    def is_valid(self):
     136        """
     137        Validates CNPJ with first 8 digits + filial digits and validation
     138        digits.
     139        This method is used in __init__ to validate number.
     140        """
     141
     142        # get company id + filial id (first 12 digits)
     143        cnpj = self.cnpj[:12]
     144       
     145        # and following rules we stabilish some weight to multiply
     146        def weightlist(s=12):
     147            x = (range(2,10)*2)[:s]
     148            x.reverse()
     149            return x
     150       
     151        # while cnpj isn't complete
     152        while len(cnpj) < 14:
     153
     154            # run trought numbers (x) mutiplying by weight (y) and then get
     155            # sum of rest of division by 11 as interger
     156            # (we have more than 9 digits so isn't simple as make calcs for CPF)
     157            r = int(sum([x*y for (x, y) in zip(cnpj, weightlist(len(cnpj)))]) % 11)
     158
     159            # if digit is smaller than 2, turns 0
     160            if r < 2:
     161                f = 0
     162            else:
     163                f = 11 - r
     164
     165            # append digit to cnpj
     166            cnpj.append(f)
     167
     168        # if created number is same as original number, cnpj is valid
     169        return bool(cnpj == self.cnpj)
     170
     171    @property
     172    def single(self):
     173        """ returns single cnpj number (without '.', '/' and '-') """
     174        return u''.join([str(x) for x in self.cnpj])
     175
     176# Based in http://www.python.org.br/wiki/VerificadorDeCpf
     177class CPF(object):
     178    """
     179    This class represents a CPF number
     180    A CPF number is compounded by XXX.XXX.XXX-VD. The two last digits are
     181    verification digits.
     182   
     183    More information:
     184    http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
     185
     186    >>> a = CPF(95524361503)
     187    >>> b = CPF('95524361503')
     188    >>> c = CPF('955.243.615-03')
     189    >>> d = CPF([9, 5, 5, 2, 4, 3, 6, 1, 5, 0, 3])
     190    >>> e = CPF(['9', '5', '5', '2', '4', '3', '6', '1', '5', '0', '3'])
     191    >>>
     192    >>> a == b, a == c, a == d, a == e
     193    (True, True, True, True)
     194
     195    """
     196   
     197    # cpfs with same number in all digits isn't valid
     198    invalid_cpfs=map(lambda x: [x for i in range(11)],xrange(1,9))
     199
     200    error_messages = {
     201        'invalid': _(u"Invalid CPF number."),
     202        'max_digits': _(u"CPF requires at most 11 digits or 14 characters."),
     203        'digits_only': _(u"CPF requires only numbers, allow '.' and '-' for long format."),
     204    }
     205   
     206    def __init__(self, cpf):
     207
     208        # transform list or int or long in a string
     209        if type(cpf) in (int,long):
     210            cpf = u"%s" % cpf
     211        if type(cpf) in (list,tuple):
     212            cpf= u''.join([str(x) for x in cpf])
     213
     214        try:
     215            basestring
     216        except:
     217            basestring = (str, unicode)
     218       
     219        # only numbers = 11, numbers + '.' and '_' = 14
     220        if len(cpf) not in (11,14):
     221            # need to be xxxxxxxxxxx or xxx.xxx.xxx-xx
     222            raise ValueError(self.error_messages['max_digits'])
     223
     224        if isinstance(cpf, basestring):
     225            # remove characters
     226            cpf = cpf.replace(".", "")
     227            cpf = cpf.replace("-", "")
     228            # and check if is digit
     229            if not cpf.isdigit():
     230                raise ValueError(self.error_messages['digits_only'])
     231       
     232        # turn into a list of integers
     233        self.cpf = map(int, cpf)
     234
     235        # validate number and validation digits
     236        if not self.is_valid:
     237            raise ValueError(self.error_messages['invalid'])
     238
     239    def __getitem__(self, index):
     240        """
     241        Returns digit at index in CPF
     242
     243        >>> a = CPF('95524361503')
     244        >>> a[9] == '0'
     245        True
     246        >>> a[10] == '3'
     247        True
     248        >>> a[9] == 0
     249        False
     250        >>> a[10] == 3
     251        False
     252
     253        """
     254        return str(self.cpf[index])
     255
     256    def __repr__(self):
     257        return "CPF('%s')" % ''.join([str(x) for x in self.cpf])
     258
     259    def __eq__(self, other):
     260        """
     261        >>> a = CPF('95524361503')
     262        >>> b = CPF('955.243.615-03')
     263        >>> c = CPF('123.456.789-00')
     264        >>> a == b
     265        True
     266        >>> a != c
     267        True
     268        >>> b != c
     269        True
     270        """
     271        if isinstance(other, CPF):
     272            return self.cpf == other.cpf
     273        return False
     274   
     275    def __unicode__(self):
     276        """
     277        Return CPF in long format, with '.' and '-'. For simple format use
     278        CPF(..).single property/method
     279
     280        >>> a = CPF('95524361503')
     281        >>> str(a)
     282        u'955.243.615-03'
     283        """
     284       
     285        d = ((3, "."), (7, "."), (11, "-"))
     286        s = map(str, self.cpf)
     287
     288        for i, v in d:
     289            s.insert(i, v)
     290       
     291        r = ''.join(s)
     292       
     293        return r
     294
     295    def __str__(self):
     296        return self.__unicode__()
     297
     298    def __len__(self):
     299        return len(self.cpf)
     300   
     301    @property
     302    def is_valid(self):
     303        """
     304        Validates CPF number with 9 digits + validation digits.
     305        This method is used to __init__ to validate number.
     306        """
     307        # check if cpf isn't in invalid_cpfs list
     308        if self.cpf in self.invalid_cpfs: return False
     309
     310        # get first nine digits to calculate two verification digits
     311        cpf = self.cpf[:9]
     312        # while cpf isn't complete (this runs two loops)
     313        while len(cpf) < 11:
     314
     315            # run trought numbers multiplying number (v) by weight (len(cpf)+1-i)
     316            # and then get sum rest of division by 11 as integer
     317            r = int(sum(map(lambda(i,v):math.floor((len(cpf)+1-i)*v),enumerate(cpf))) % 11)
     318
     319            # if digit is smaller than 2, turns 0
     320            if r < 2:
     321                f = 0
     322            else:
     323                f = 11 -r
     324           
     325            # append to cpf list
     326            cpf.append(f)
     327
     328        # if created number is same as original number, cpf is valid
     329        return bool(cpf == self.cpf)
     330
     331    def __nonzero__(self):
     332        return self.is_valid
     333   
     334    @property
     335    def single(self):
     336        """ returns single cpf number (without '.' and '-') """
     337        return u''.join([str(x) for x in self.cpf])
     338
     339def get_digits(randns,d1weight,d2weight):
     340    """
     341    return a tuple with cpf or cnpj digits. we use same method to get
     342    digits based on numbers and weights
     343    """
     344
     345    # GET FIRST CHECK DIGIT
     346
     347    # multiply by weightlist for first digit
     348    d1ns = [randns[i]*m for i,m in enumerate(d1weight)]
     349
     350    # get sum
     351    d1sum = sum(d1ns)
     352   
     353    # get firts digit. if first digit >= 10, transform in 0
     354    d1 = int(round(d1sum - (math.floor(d1sum/11)*11)))
     355    if d1 < 2:
     356        d1 = 0
     357    else:
     358        d1 = 11 - d1
     359
     360    # GET SECOND CHECK DIGIT
     361
     362    # multipy by weightlist for second digit, but add first digit in list
     363    d2ns = (lambda: [(randns+[d1])[i]*m for i,m in enumerate(d2weight)])()
     364
     365    # get sum
     366    d2sum = sum(d2ns)
     367   
     368    # get second digit. if second digit >= 10, transform in 0
     369    d2 = int(round(d2sum - (math.floor(d2sum/11)*11)))
     370    if d2 < 2:
     371        d2 = 0
     372    else:
     373        d2 = 11 - d2
     374
     375    return d1,d2
     376
     377def CPFGenerator(amount=1,cpfn=None):
     378    """ generate valid cpf for tests """
     379
     380    # randnumbers are created from 0 to 9, and multiplicated by these list for
     381    # fist digit
     382    d1weight = range(2,11) # [2,3,...,10]
     383    d1weight.reverse()
     384   
     385    # for second digit same as for first digit, but with d1
     386    d2weight = range(2,12) # [2,3,...,11]
     387    d2weight.reverse()
     388
     389    # create how many cpfs amount says then add to set cpfs
     390    cpfs=set()
     391
     392    while len(cpfs) < amount:
     393        # get some rand numbers
     394        if not cpfn:
     395            randns = [randint(0,9) for x in range(9)]
     396        else:
     397            randns = cpfn
     398       
     399        d1,d2 = get_digits(randns,d1weight,d2weight)
     400
     401        # transform cpf in a string
     402        cpf = ("%s"*11) % tuple(randns+[d1,d2])
     403       
     404        # if not exist, add in cpfs
     405        if not cpf in cpfs:
     406            cpfs.add(cpf)
     407
     408    cpfs = list(cpfs)
     409    if len(cpfs) != 1:
     410        return cpfs
     411    else:
     412        return cpfs[0]
     413
     414def CNPJGenerator(amount=1,cnpjn=None):
     415    """ generate valid cnpj for tests """
     416
     417    d1weight = [5,4,3,2,9,8,7,6,5,4,3,2]
     418    d2weight = [6] + d1weight
     419   
     420    cnpjs=set()
     421
     422    while len(cnpjs) < amount:
     423
     424        if not cnpjn:
     425            randns = [randint(0,9) for x in range(8)] + [0,0,0,randint(0,9)]
     426        else:
     427            randns = cnpjn
     428
     429        d1,d2 = get_digits(randns,d1weight,d2weight)
     430
     431        # transform cnpj in a string
     432        cnpj = ("%s"*14) % tuple(randns+[d1,d2])
     433       
     434        # if not exist, add in cnpjs
     435        if not cnpj in cnpjs:
     436            cnpjs.add(cnpj)
     437
     438    cnpjs = list(cnpjs)
     439    if len(cnpjs) != 1:
     440        return cnpjs
     441    else:
     442        return cnpjs[0]
     443
     444
  • django/contrib/localflavor/br/forms.py

    diff --git a/django/contrib/localflavor/br/forms.py b/django/contrib/localflavor/br/forms.py
    index 7a7a858..7fad404 100644
    a b from django.forms import ValidationError 
    88from django.forms.fields import Field, RegexField, CharField, Select
    99from django.utils.encoding import smart_unicode
    1010from django.utils.translation import ugettext_lazy as _
     11from django.contrib.localflavor.br.br_cpfcnpj import CPF,CNPJ
    1112import re
    1213
    1314phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$')
    class BRStateChoiceField(Field): 
    7374            raise ValidationError(self.error_messages['invalid'])
    7475        return value
    7576
    76 def DV_maker(v):
    77     if v >= 2:
    78         return 11 - v
    79     return 0
    80 
    8177class BRCPFField(CharField):
    8278    """
    8379    This field validate a CPF number or a CPF string. A CPF number is
    class BRCPFField(CharField): 
    9389    }
    9490
    9591    def __init__(self, *args, **kwargs):
    96         super(BRCPFField, self).__init__(max_length=14, min_length=11, *args, **kwargs)
     92        kwargs['max_length'] = 14
     93        kwargs['min_length'] = 11
     94        super(BRCPFField, self).__init__(*args, **kwargs)
    9795
    9896    def clean(self, value):
    9997        """
    class BRCPFField(CharField): 
    10199        11-digit number.
    102100        """
    103101        value = super(BRCPFField, self).clean(value)
    104         if value in EMPTY_VALUES:
    105             return u''
    106         orig_value = value[:]
    107         if not value.isdigit():
    108             value = re.sub("[-\.]", "", value)
     102        if not self.required and value in EMPTY_VALUES:
     103            return value
     104
    109105        try:
    110             int(value)
    111         except ValueError:
    112             raise ValidationError(self.error_messages['digits_only'])
    113         if len(value) != 11:
    114             raise ValidationError(self.error_messages['max_digits'])
    115         orig_dv = value[-2:]
    116 
    117         new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
    118         new_1dv = DV_maker(new_1dv % 11)
    119         value = value[:-2] + str(new_1dv) + value[-1]
    120         new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(11, 1, -1))])
    121         new_2dv = DV_maker(new_2dv % 11)
    122         value = value[:-1] + str(new_2dv)
    123         if value[-2:] != orig_dv:
    124             raise ValidationError(self.error_messages['invalid'])
     106            cpf = CPF(value)
     107        except ValueError,err:
     108            # CPF class already raise internal erros if cpf isn't valid
     109            raise ValidationError,err
    125110
    126         return orig_value
     111        return value
    127112
    128 class BRCNPJField(Field):
    129     default_error_messages = {
    130         'invalid': _("Invalid CNPJ number."),
    131         'digits_only': _("This field requires only numbers."),
    132         'max_digits': _("This field requires at least 14 digits"),
    133     }
     113class BRCNPJField(CharField):
     114    """
     115    This field validate a CNPJ number or a CNPJ string. A CNPJ number is
     116    compounded by XX.XXX.XXX/XXXX-VD. The two last digits are check digits.
     117    """
     118
     119    def __init__(self,*args,**kwargs):
     120        kwargs['max_length'] = 18
     121        kwargs['min_length'] = 14
     122        super(BRCNPJField,self).__init__(*args,**kwargs)
    134123
    135124    def clean(self, value):
    136125        """
    class BRCNPJField(Field): 
    138127        group of 14 characters.
    139128        """
    140129        value = super(BRCNPJField, self).clean(value)
    141         if value in EMPTY_VALUES:
    142             return u''
    143         orig_value = value[:]
    144         if not value.isdigit():
    145             value = re.sub("[-/\.]", "", value)
     130        if not self.required and value in EMPTY_VALUES:
     131            return value
     132
    146133        try:
    147             int(value)
    148         except ValueError:
    149             raise ValidationError(self.error_messages['digits_only'])
    150         if len(value) != 14:
    151             raise ValidationError(self.error_messages['max_digits'])
    152         orig_dv = value[-2:]
    153 
    154         new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))])
    155         new_1dv = DV_maker(new_1dv % 11)
    156         value = value[:-2] + str(new_1dv) + value[-1]
    157         new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(6, 1, -1) + range(9, 1, -1))])
    158         new_2dv = DV_maker(new_2dv % 11)
    159         value = value[:-1] + str(new_2dv)
    160         if value[-2:] != orig_dv:
    161             raise ValidationError(self.error_messages['invalid'])
     134            cnpj = CNPJ(value)
     135        except ValueError,err:
     136            # CNPJ class already raise internal errors if CNPJ isn't valid
     137            raise ValidationError,err
    162138
    163         return orig_value
     139        return value
  • new file django/contrib/localflavor/br/models.py

    diff --git a/django/contrib/localflavor/br/models.py b/django/contrib/localflavor/br/models.py
    new file mode 100644
    index 0000000..b3f5ae5
    - +  
     1from django.db import models
     2from django.contrib.localflavor.br.br_cpfcnpj import CPF,CNPJ
     3from django.contrib.localflavor.br import forms
     4
     5EMPTY_VALUES=(None,'')
     6
     7class BRCPFField(models.CharField):
     8    """ CPF Model field """
     9    description = "The Brazilian CPF Field"
     10
     11    __metaclass__ = models.SubfieldBase
     12
     13    def __init__(self,*args,**kwargs):
     14        self.longformat = kwargs.pop('longformat',False)
     15        kwargs['max_length'] = 14 if self.longformat else 11
     16        super(BRCPFField,self).__init__(*args,**kwargs)
     17
     18    def get_internal_type(self):
     19        return "CharField"
     20
     21    def formfield(self,**kwargs):
     22        defaults = {'form_class': forms.BRCPFField}
     23        defaults.update(kwargs)
     24        return super(BRCPFField,self).formfield(**defaults)
     25
     26    def to_python(self,value):
     27        """ convert string from base to a CPF instance """
     28        if isinstance(value,CPF) or value in EMPTY_VALUES:
     29            return value
     30        try:
     31            return CPF(value)
     32        except TypeError:
     33            return None
     34
     35    def get_prep_value(self,value):
     36        value = self.to_python(value)
     37        if not value:
     38            return ''
     39        if self.longformat:
     40            return value.__unicode__
     41        else:
     42            return value.single
     43
     44class BRCNPJField(models.CharField):
     45    """ CNPJ Model field """
     46    description = "The Brazilian CNPJ Field"
     47
     48    __metaclass__ = models.SubfieldBase
     49
     50    def __init__(self,*args,**kwargs):
     51        self.longformat = kwargs.pop('longformat',False)
     52        kwargs['max_length'] = 18 if self.longformat else 14
     53        super(BRCNPJField,self).__init__(*args,**kwargs)
     54
     55    def get_internal_type(self):
     56        return "CharField"
     57
     58    def formfield(self,**kwargs):
     59        defaults = {'form_class': forms.BRCNPJField}
     60        defaults.update(kwargs)
     61        return super(BRCNPJField,self).formfield(**defaults)
     62
     63    def to_python(self,value):
     64        """ convert string from base to a CNPJ instance """
     65        if isinstance(value,CNPJ) or value in EMPTY_VALUES:
     66            return value
     67        try:
     68            return CNPJ(value)
     69        except TypeError:
     70            return None
     71
     72    def get_prep_value(self,value):
     73        value = self.to_python(value)
     74        if not value:
     75            return ''
     76        if self.longformat:
     77            return value.__unicode__
     78        else:
     79            return value.single
  • tests/regressiontests/forms/localflavor/br.py

    diff --git a/tests/regressiontests/forms/localflavor/br.py b/tests/regressiontests/forms/localflavor/br.py
    index 757f382..aa04aa3 100644
    a b ValidationError: [u'Enter a zip code in the format XXXXX-XXX.'] 
    6464>>> f.clean('12345-123')
    6565u'12345-123'
    6666
    67 # BRCNPJField ############################################################
    68 
    69 >>> from django.contrib.localflavor.br.forms import BRCNPJField
    70 >>> f = BRCNPJField(required=True)
    71 >>> f.clean('')
    72 Traceback (most recent call last):
    73 ...
    74 ValidationError: [u'This field is required.']
    75 >>> f.clean('12-345-678/9012-10')
    76 Traceback (most recent call last):
    77 ...
    78 ValidationError: [u'Invalid CNPJ number.']
    79 >>> f.clean('12.345.678/9012-10')
    80 Traceback (most recent call last):
    81 ...
    82 ValidationError: [u'Invalid CNPJ number.']
    83 >>> f.clean('12345678/9012-10')
    84 Traceback (most recent call last):
    85 ...
    86 ValidationError: [u'Invalid CNPJ number.']
    87 >>> f.clean('64.132.916/0001-88')
    88 '64.132.916/0001-88'
    89 >>> f.clean('64-132-916/0001-88')
    90 '64-132-916/0001-88'
    91 >>> f.clean('64132916/0001-88')
    92 '64132916/0001-88'
    93 >>> f.clean('64.132.916/0001-XX')
    94 Traceback (most recent call last):
    95 ...
    96 ValidationError: [u'This field requires only numbers.']
    97 >>> f = BRCNPJField(required=False)
    98 >>> f.clean('')
    99 u''
    100 
    101 # BRCPFField #################################################################
    102 
    103 >>> from django.contrib.localflavor.br.forms import BRCPFField
    104 >>> f = BRCPFField()
    105 >>> f.clean('')
    106 Traceback (most recent call last):
    107 ...
    108 ValidationError: [u'This field is required.']
    109 >>> f.clean(None)
    110 Traceback (most recent call last):
    111 ...
    112 ValidationError: [u'This field is required.']
    113 >>> f.clean('489.294.654-54')
    114 Traceback (most recent call last):
    115 ...
    116 ValidationError: [u'Invalid CPF number.']
    117 >>> f.clean('295.669.575-98')
    118 Traceback (most recent call last):
    119 ...
    120 ValidationError: [u'Invalid CPF number.']
    121 >>> f.clean('539.315.127-22')
    122 Traceback (most recent call last):
    123 ...
    124 ValidationError: [u'Invalid CPF number.']
    125 >>> f.clean('663.256.017-26')
    126 u'663.256.017-26'
    127 >>> f.clean('66325601726')
    128 u'66325601726'
    129 >>> f.clean('375.788.573-20')
    130 u'375.788.573-20'
    131 >>> f.clean('84828509895')
    132 u'84828509895'
    133 >>> f.clean('375.788.573-XX')
    134 Traceback (most recent call last):
    135 ...
    136 ValidationError: [u'This field requires only numbers.']
    137 >>> f.clean('375.788.573-000')
    138 Traceback (most recent call last):
    139 ...
    140 ValidationError: [u'Ensure this value has at most 14 characters (it has 15).']
    141 >>> f.clean('123.456.78')
    142 Traceback (most recent call last):
    143 ...
    144 ValidationError: [u'Ensure this value has at least 11 characters (it has 10).']
    145 >>> f.clean('123456789555')
    146 Traceback (most recent call last):
    147 ...
    148 ValidationError: [u'This field requires at most 11 digits or 14 characters.']
    149 >>> f = BRCPFField(required=False)
    150 >>> f.clean('')
    151 u''
    152 >>> f.clean(None)
    153 u''
    154 
    15567# BRPhoneNumberField #########################################################
    15668
    15769>>> from django.contrib.localflavor.br.forms import BRPhoneNumberField
  • deleted file tests/regressiontests/localflavor/forms.py

    diff --git a/tests/regressiontests/localflavor/__init__.py b/tests/regressiontests/localflavor/__init__.py
    deleted file mode 100644
    index e69de29..0000000
    diff --git a/tests/regressiontests/localflavor/forms.py b/tests/regressiontests/localflavor/forms.py
    deleted file mode 100644
    index 2dd1da6..0000000
    + -  
    1 from django.forms import ModelForm
    2 from models import Place
    3 
    4 class PlaceForm(ModelForm):
    5     """docstring for PlaceForm"""
    6     class Meta:
    7         model = Place
  • deleted file tests/regressiontests/localflavor/models.py

    diff --git a/tests/regressiontests/localflavor/models.py b/tests/regressiontests/localflavor/models.py
    deleted file mode 100644
    index f74a505..0000000
    + -  
    1 from django.db import models
    2 from django.contrib.localflavor.us.models import USStateField
    3 
    4 class Place(models.Model):
    5     state = USStateField(blank=True)
    6     state_req = USStateField()
    7     state_default = USStateField(default="CA", blank=True)
    8     name = models.CharField(max_length=20)
  • deleted file tests/regressiontests/localflavor/tests.py

    diff --git a/tests/regressiontests/localflavor/tests.py b/tests/regressiontests/localflavor/tests.py
    deleted file mode 100644
    index 0ea3c52..0000000
    + -  
    1 from django.test import TestCase
    2 from models import Place
    3 from forms import PlaceForm
    4 
    5 class USLocalflavorTests(TestCase):
    6     def setUp(self):
    7         self.form = PlaceForm({'state':'GA', 'state_req':'NC', 'name':'impossible'})
    8        
    9     def test_get_display_methods(self):
    10         """Test that the get_*_display() methods are added to the model instances."""
    11         place = self.form.save()
    12         self.assertEqual(place.get_state_display(), 'Georgia')
    13         self.assertEqual(place.get_state_req_display(), 'North Carolina')
    14    
    15     def test_required(self):
    16         """Test that required USStateFields throw appropriate errors."""
    17         form = PlaceForm({'state':'GA', 'name':'Place in GA'})
    18         self.assertFalse(form.is_valid())
    19         self.assertEqual(form.errors['state_req'], [u'This field is required.'])
    20    
    21     def test_field_blank_option(self):
    22         """Test that the empty option is there."""
    23         state_select_html = """\
    24 <select name="state" id="id_state">
    25 <option value="">---------</option>
    26 <option value="AL">Alabama</option>
    27 <option value="AK">Alaska</option>
    28 <option value="AS">American Samoa</option>
    29 <option value="AZ">Arizona</option>
    30 <option value="AR">Arkansas</option>
    31 <option value="CA">California</option>
    32 <option value="CO">Colorado</option>
    33 <option value="CT">Connecticut</option>
    34 <option value="DE">Delaware</option>
    35 <option value="DC">District of Columbia</option>
    36 <option value="FL">Florida</option>
    37 <option value="GA" selected="selected">Georgia</option>
    38 <option value="GU">Guam</option>
    39 <option value="HI">Hawaii</option>
    40 <option value="ID">Idaho</option>
    41 <option value="IL">Illinois</option>
    42 <option value="IN">Indiana</option>
    43 <option value="IA">Iowa</option>
    44 <option value="KS">Kansas</option>
    45 <option value="KY">Kentucky</option>
    46 <option value="LA">Louisiana</option>
    47 <option value="ME">Maine</option>
    48 <option value="MD">Maryland</option>
    49 <option value="MA">Massachusetts</option>
    50 <option value="MI">Michigan</option>
    51 <option value="MN">Minnesota</option>
    52 <option value="MS">Mississippi</option>
    53 <option value="MO">Missouri</option>
    54 <option value="MT">Montana</option>
    55 <option value="NE">Nebraska</option>
    56 <option value="NV">Nevada</option>
    57 <option value="NH">New Hampshire</option>
    58 <option value="NJ">New Jersey</option>
    59 <option value="NM">New Mexico</option>
    60 <option value="NY">New York</option>
    61 <option value="NC">North Carolina</option>
    62 <option value="ND">North Dakota</option>
    63 <option value="MP">Northern Mariana Islands</option>
    64 <option value="OH">Ohio</option>
    65 <option value="OK">Oklahoma</option>
    66 <option value="OR">Oregon</option>
    67 <option value="PA">Pennsylvania</option>
    68 <option value="PR">Puerto Rico</option>
    69 <option value="RI">Rhode Island</option>
    70 <option value="SC">South Carolina</option>
    71 <option value="SD">South Dakota</option>
    72 <option value="TN">Tennessee</option>
    73 <option value="TX">Texas</option>
    74 <option value="UT">Utah</option>
    75 <option value="VT">Vermont</option>
    76 <option value="VI">Virgin Islands</option>
    77 <option value="VA">Virginia</option>
    78 <option value="WA">Washington</option>
    79 <option value="WV">West Virginia</option>
    80 <option value="WI">Wisconsin</option>
    81 <option value="WY">Wyoming</option>
    82 </select>"""
    83         self.assertEqual(str(self.form['state']), state_select_html)
  • new file tests/regressiontests/localflavor_regress/br/forms.py

    diff --git a/tests/regressiontests/localflavor_regress/__init__.py b/tests/regressiontests/localflavor_regress/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/localflavor_regress/br/__init__.py b/tests/regressiontests/localflavor_regress/br/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/localflavor_regress/br/forms.py b/tests/regressiontests/localflavor_regress/br/forms.py
    new file mode 100644
    index 0000000..08afd36
    - +  
     1from django import forms
     2from models import BRCPFCNPJ
     3
     4class BRCPFCNPJForm(forms.ModelForm):
     5
     6    class Meta:
     7        model = BRCPFCNPJ
  • new file tests/regressiontests/localflavor_regress/br/models.py

    diff --git a/tests/regressiontests/localflavor_regress/br/models.py b/tests/regressiontests/localflavor_regress/br/models.py
    new file mode 100644
    index 0000000..a2b33bf
    - +  
     1from django.db import models
     2from django.contrib.localflavor.br.models import BRCPFField, BRCNPJField
     3
     4class BRCPFCNPJ(models.Model):
     5
     6    cpf = BRCPFField()
     7    cnpj = BRCNPJField()
     8
     9    def __unicode__(self):
     10        return u"%s ,  %s" % (self.cpf,self.cnpj)
     11
     12    class Meta:
     13        app_label = 'localflavor_regress'
     14
     15class BRCPFCNPJ2(models.Model):
     16
     17    cpf = BRCPFField(blank=True)
     18    cnpj = BRCNPJField(blank=True)
     19
     20    def __unicode__(self):
     21        return u"%s ,  %s" % (self.cpf,self.cnpj)
     22
     23    class Meta:
     24        app_label = 'localflavor_regress'
  • new file tests/regressiontests/localflavor_regress/br/tests.py

    diff --git a/tests/regressiontests/localflavor_regress/br/tests.py b/tests/regressiontests/localflavor_regress/br/tests.py
    new file mode 100644
    index 0000000..096754d
    - +  
     1from django.test import TestCase
     2from django import forms
     3from django.contrib.localflavor.br.br_cpfcnpj import CPF, CNPJ, CPFGenerator,\
     4    CNPJGenerator
     5from django.contrib.localflavor.br import forms as brforms
     6from models import BRCPFCNPJ, BRCPFCNPJ2
     7from forms import BRCPFCNPJForm
     8
     9from random import choice
     10
     11class BRCPFCNPJTests(TestCase):
     12
     13    @property
     14    def randomcpf(self):
     15        return CPFGenerator()
     16
     17    @property
     18    def randomcnpj(self):
     19        return CNPJGenerator()
     20
     21    def test_cpf_type(self):
     22        """ make tests on cpf class """
     23        cpf = '43502207046'
     24
     25        # test wrong size
     26        try:
     27            CPF(cpf[:-1])
     28        except ValueError,err:
     29            self.assertEqual(err.args,(CPF.error_messages['max_digits'],))
     30
     31        # test digits only
     32        try:
     33            CPF(cpf.replace('0','a'))
     34        except ValueError,err:
     35            self.assertEqual(err.args,(CPF.error_messages['digits_only'],))
     36
     37        # test invalid cpf
     38        try:
     39            CPF(cpf[:-1]+'5')
     40        except ValueError,err:
     41            self.assertEqual(err.args,(CPF.error_messages['invalid'],))
     42
     43        # test valid cpf
     44        try:
     45            cpfn = CPF(cpf)
     46        except ValueError,err:
     47            self.fail(str(err))
     48   
     49    def test_cnpj_type(self):
     50        """ make tests on cnpj type """
     51        cnpj = '59430995000173'
     52
     53        # test wrong size
     54        try:
     55            CNPJ(cnpj[:-1])
     56        except ValueError,err:
     57            self.assertEqual(err.args,(CNPJ.error_messages['max_digits'],))
     58
     59        # test digits only
     60        try:
     61            CNPJ(cnpj.replace('0','a'))
     62        except ValueError,err:
     63            self.assertEqual(err.args,(CNPJ.error_messages['digits_only'],))
     64
     65        # test invalid cnpj
     66        try:
     67            CNPJ(cnpj[:-1]+'5')
     68        except ValueError,err:
     69            self.assertEqual(err.args,(CNPJ.error_messages['invalid'],))
     70
     71        # test valid cnpj
     72        try:
     73            cnpjn = CNPJ(cnpj)
     74        except ValueError,err:
     75            self.fail(str(err))
     76
     77    def test_cpf_generator(self):
     78        # create 100 CPFS with generator
     79        for i in xrange(100):
     80            try:
     81                CPF(self.randomcpf)
     82            except ValueError,err:
     83                self.fail(str(err))
     84
     85    def test_cnpj_generator(self):
     86        # create 100 CNPJS with generator
     87        for i in xrange(100):
     88            try:
     89                CNPJ(self.randomcnpj)
     90            except ValueError,err:
     91                self.fail(str(err))
     92
     93    def test_cpfcnpj_form_and_model(self):
     94        # inserts 100 register on cpfcnpj model with form
     95        for i in xrange(100):
     96            cpf = self.randomcpf
     97            cnpj = self.randomcnpj
     98
     99            # just choice over full number cpf/cnpj, normal string or with
     100            # additional characters, so we test with that various formats on
     101            # form input
     102            cpf_to_form = choice([cpf,str(CPF(cpf)),CPF(cpf).single])
     103            cnpj_to_form = choice([cnpj,str(CNPJ(cnpj)),CNPJ(cnpj).single])
     104           
     105            f = BRCPFCNPJForm(data={'cpf':cpf_to_form,'cnpj':cnpj_to_form})
     106
     107            if f.is_valid():
     108                f.save()
     109            else:
     110                # show any errors
     111                self.fail(u"\n".join(["\n%s: %s" % (k.upper(),u', '.join(v)) for k,v in f.errors.items()]))
     112                break
     113
     114            try:
     115                inst = BRCPFCNPJ.objects.get(cpf=cpf,cnpj=cnpj)
     116            except BRCPFCNPJ.DoesNotExist:
     117                self.fail("Failed on get saved cpf/cnpj with form")
     118                break
     119            else:
     120                # check if numbers are equal
     121                self.assertEqual(cpf,inst.cpf.single)
     122                self.assertEqual(cnpj,inst.cnpj.single)
     123
     124
     125    def test_cpfcnpj_simpleform(self):
     126        """ test single form with blank value and normal value """
     127
     128        class Form1(forms.Form):
     129            cpf = brforms.BRCPFField(required=False)
     130            def save(self):
     131                return self.cleaned_data
     132        class Form2(forms.Form):
     133            cnpj = brforms.BRCNPJField(required=False)
     134            def save(self):
     135                return self.cleaned_data
     136
     137
     138        cpf = CPFGenerator()
     139        cnpj = CNPJGenerator()
     140
     141        """ with cpf """
     142        f = Form1(data={'cpf':cpf})
     143        self.assertEqual(f.is_valid(),True)
     144        self.assertEqual({'cpf':cpf},f.save())
     145        """ without cpf """
     146        f = Form1(data={'cpf':''})
     147        self.assertEqual(f.is_valid(),True)
     148        self.assertEqual({'cpf':''},f.save())
     149
     150
     151        """ with cnpj """
     152        f = Form2(data={'cnpj':cnpj})
     153        self.assertEqual(f.is_valid(),True)
     154        self.assertEqual({'cnpj':cnpj},f.save())
     155        """ without cnpj """
     156        f = Form2(data={'cnpj':''})
     157        self.assertEqual(f.is_valid(),True)
     158        self.assertEqual({'cnpj':''},f.save())
     159
     160    def test_cpfcnpj_blank_model_form(self):
     161        """ test blank=True for models and forms """
     162
     163        class Form1(forms.ModelForm):
     164
     165            class Meta:
     166                model = BRCPFCNPJ2
     167
     168        f = Form1(data={'cpf':'','cnpj':''})
     169        self.assertEqual(f.is_valid(),True)
     170        self.assertEqual({'cnpj':'','cpf':''},f.cleaned_data)
     171        f.save()
     172        m = BRCPFCNPJ2.objects.get(pk=1)
     173        self.assertEqual(m.cpf,'')
     174        self.assertEqual(m.cnpj,'')
     175
     176
  • new file tests/regressiontests/localflavor_regress/tests.py

    diff --git a/tests/regressiontests/localflavor_regress/models.py b/tests/regressiontests/localflavor_regress/models.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/localflavor_regress/tests.py b/tests/regressiontests/localflavor_regress/tests.py
    new file mode 100644
    index 0000000..8772b68
    - +  
     1import unittest
     2from django.test import TestCase
     3
     4# just import your tests here
     5from us.tests import *
     6from br.tests import *
     7
     8# Get every subclass of TestCase and add to suite
     9# Now script check for every imported class, if is a subclass of TestCase add
     10# to testlist, and then suite create a TestSuite with these clases.
     11testlist=[]
     12for i in locals().values():
     13    try:
     14        if issubclass(i,TestCase) and i is not TestCase:
     15            testlist.append(unittest.TestLoader().loadTestsFromTestCase(i))
     16    except TypeError:
     17        pass
     18
     19def suite():
     20    return unittest.TestSuite(list(testlist))
     21
  • new file tests/regressiontests/localflavor_regress/us/forms.py

    diff --git a/tests/regressiontests/localflavor_regress/us/__init__.py b/tests/regressiontests/localflavor_regress/us/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/localflavor_regress/us/forms.py b/tests/regressiontests/localflavor_regress/us/forms.py
    new file mode 100644
    index 0000000..9b77e10
    - +  
     1from django.forms import ModelForm
     2from models import USPlace
     3
     4class USPlaceForm(ModelForm):
     5    """docstring for PlaceForm"""
     6    class Meta:
     7        model = USPlace
  • new file tests/regressiontests/localflavor_regress/us/models.py

    diff --git a/tests/regressiontests/localflavor_regress/us/models.py b/tests/regressiontests/localflavor_regress/us/models.py
    new file mode 100644
    index 0000000..f944014
    - +  
     1from django.db import models
     2from django.contrib.localflavor.us.models import USStateField
     3
     4# When creating models you need to remember to add a app_label as
     5# 'localflavor_regress', so your model can be found
     6
     7class USPlace(models.Model):
     8    state = USStateField(blank=True)
     9    state_req = USStateField()
     10    state_default = USStateField(default="CA", blank=True)
     11    name = models.CharField(max_length=20)
     12    class Meta:
     13        app_label = 'localflavor_regress'
  • new file tests/regressiontests/localflavor_regress/us/tests.py

    diff --git a/tests/regressiontests/localflavor_regress/us/tests.py b/tests/regressiontests/localflavor_regress/us/tests.py
    new file mode 100644
    index 0000000..e85f0ad
    - +  
     1from django.test import TestCase
     2from forms import USPlaceForm
     3
     4class USLocalflavorTests(TestCase):
     5    def setUp(self):
     6        self.form = USPlaceForm({'state':'GA', 'state_req':'NC', 'name':'impossible'})
     7       
     8    def test_get_display_methods(self):
     9        """Test that the get_*_display() methods are added to the model instances."""
     10        place = self.form.save()
     11        self.assertEqual(place.get_state_display(), 'Georgia')
     12        self.assertEqual(place.get_state_req_display(), 'North Carolina')
     13   
     14    def test_required(self):
     15        """Test that required USStateFields throw appropriate errors."""
     16        form = USPlaceForm({'state':'GA', 'name':'Place in GA'})
     17        self.assertFalse(form.is_valid())
     18        self.assertEqual(form.errors['state_req'], [u'This field is required.'])
     19   
     20    def test_field_blank_option(self):
     21        """Test that the empty option is there."""
     22        state_select_html = """\
     23<select name="state" id="id_state">
     24<option value="">---------</option>
     25<option value="AL">Alabama</option>
     26<option value="AK">Alaska</option>
     27<option value="AS">American Samoa</option>
     28<option value="AZ">Arizona</option>
     29<option value="AR">Arkansas</option>
     30<option value="CA">California</option>
     31<option value="CO">Colorado</option>
     32<option value="CT">Connecticut</option>
     33<option value="DE">Delaware</option>
     34<option value="DC">District of Columbia</option>
     35<option value="FL">Florida</option>
     36<option value="GA" selected="selected">Georgia</option>
     37<option value="GU">Guam</option>
     38<option value="HI">Hawaii</option>
     39<option value="ID">Idaho</option>
     40<option value="IL">Illinois</option>
     41<option value="IN">Indiana</option>
     42<option value="IA">Iowa</option>
     43<option value="KS">Kansas</option>
     44<option value="KY">Kentucky</option>
     45<option value="LA">Louisiana</option>
     46<option value="ME">Maine</option>
     47<option value="MD">Maryland</option>
     48<option value="MA">Massachusetts</option>
     49<option value="MI">Michigan</option>
     50<option value="MN">Minnesota</option>
     51<option value="MS">Mississippi</option>
     52<option value="MO">Missouri</option>
     53<option value="MT">Montana</option>
     54<option value="NE">Nebraska</option>
     55<option value="NV">Nevada</option>
     56<option value="NH">New Hampshire</option>
     57<option value="NJ">New Jersey</option>
     58<option value="NM">New Mexico</option>
     59<option value="NY">New York</option>
     60<option value="NC">North Carolina</option>
     61<option value="ND">North Dakota</option>
     62<option value="MP">Northern Mariana Islands</option>
     63<option value="OH">Ohio</option>
     64<option value="OK">Oklahoma</option>
     65<option value="OR">Oregon</option>
     66<option value="PA">Pennsylvania</option>
     67<option value="PR">Puerto Rico</option>
     68<option value="RI">Rhode Island</option>
     69<option value="SC">South Carolina</option>
     70<option value="SD">South Dakota</option>
     71<option value="TN">Tennessee</option>
     72<option value="TX">Texas</option>
     73<option value="UT">Utah</option>
     74<option value="VT">Vermont</option>
     75<option value="VI">Virgin Islands</option>
     76<option value="VA">Virginia</option>
     77<option value="WA">Washington</option>
     78<option value="WV">West Virginia</option>
     79<option value="WI">Wisconsin</option>
     80<option value="WY">Wyoming</option>
     81</select>"""
     82        self.assertEqual(str(self.form['state']), state_select_html)
Back to Top