Ticket #13473: ticket13473.patch
File ticket13473.patch, 80.2 KB (added by , 14 years ago) |
---|
-
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 "" 5 5 msgstr "" 6 6 "Project-Id-Version: Django\n" 7 7 "Report-Msgid-Bugs-To: Grupo de Localização para o Português <django-l10n-portuguese@googlegroups.com>\n" 8 "POT-Creation-Date: 2010-0 3-19 17:38-0300\n"8 "POT-Creation-Date: 2010-05-26 00:42-0300\n" 9 9 "PO-Revision-Date: 2010-03-19 17:58-0300\n" 10 10 "Last-Translator: Guilherme Gondim <semente@taurinus.org>\n" 11 11 "Language-Team: Grupo de Localização para o Português <django-l10n-portuguese@googlegroups.com>\n" … … msgid "English" 59 59 msgstr "Inglês" 60 60 61 61 #: conf/global_settings.py:55 62 #, fuzzy 63 msgid "British English" 64 msgstr "Inglês" 65 66 #: conf/global_settings.py:56 62 67 msgid "Spanish" 63 68 msgstr "Espanhol" 64 69 65 #: conf/global_settings.py:5 670 #: conf/global_settings.py:57 66 71 msgid "Argentinean Spanish" 67 72 msgstr "Espanhol Argentino" 68 73 69 #: conf/global_settings.py:5 774 #: conf/global_settings.py:58 70 75 msgid "Estonian" 71 76 msgstr "Estoniano" 72 77 73 #: conf/global_settings.py:5 878 #: conf/global_settings.py:59 74 79 msgid "Basque" 75 80 msgstr "Basco" 76 81 77 #: conf/global_settings.py: 5982 #: conf/global_settings.py:60 78 83 msgid "Persian" 79 84 msgstr "Persa" 80 85 81 #: conf/global_settings.py:6 086 #: conf/global_settings.py:61 82 87 msgid "Finnish" 83 88 msgstr "Finlandês" 84 89 85 #: conf/global_settings.py:6 190 #: conf/global_settings.py:62 86 91 msgid "French" 87 92 msgstr "Francês" 88 93 89 #: conf/global_settings.py:6 294 #: conf/global_settings.py:63 90 95 msgid "Frisian" 91 96 msgstr "Frísia" 92 97 93 #: conf/global_settings.py:6 398 #: conf/global_settings.py:64 94 99 msgid "Irish" 95 100 msgstr "Irlandês" 96 101 97 #: conf/global_settings.py:6 4102 #: conf/global_settings.py:65 98 103 msgid "Galician" 99 104 msgstr "Galiciano" 100 105 101 #: conf/global_settings.py:6 5106 #: conf/global_settings.py:66 102 107 msgid "Hebrew" 103 108 msgstr "Hebraico" 104 109 105 #: conf/global_settings.py:6 6110 #: conf/global_settings.py:67 106 111 msgid "Hindi" 107 112 msgstr "Hindi" 108 113 109 #: conf/global_settings.py:6 7114 #: conf/global_settings.py:68 110 115 msgid "Croatian" 111 116 msgstr "Croata" 112 117 113 #: conf/global_settings.py:6 8118 #: conf/global_settings.py:69 114 119 msgid "Hungarian" 115 120 msgstr "Húngaro" 116 121 117 #: conf/global_settings.py:69 122 #: conf/global_settings.py:70 123 #, fuzzy 124 msgid "Indonesian" 125 msgstr "Macedônio" 126 127 #: conf/global_settings.py:71 118 128 msgid "Icelandic" 119 129 msgstr "Islandês" 120 130 121 #: conf/global_settings.py:7 0131 #: conf/global_settings.py:72 122 132 msgid "Italian" 123 133 msgstr "Italiano" 124 134 125 #: conf/global_settings.py:7 1135 #: conf/global_settings.py:73 126 136 msgid "Japanese" 127 137 msgstr "Japonês" 128 138 129 #: conf/global_settings.py:7 2139 #: conf/global_settings.py:74 130 140 msgid "Georgian" 131 141 msgstr "Georgiano" 132 142 133 #: conf/global_settings.py:7 3143 #: conf/global_settings.py:75 134 144 msgid "Khmer" 135 145 msgstr "Khmer" 136 146 137 #: conf/global_settings.py:7 4147 #: conf/global_settings.py:76 138 148 msgid "Kannada" 139 149 msgstr "Canarês" 140 150 141 #: conf/global_settings.py:7 5151 #: conf/global_settings.py:77 142 152 msgid "Korean" 143 153 msgstr "Coreano" 144 154 145 #: conf/global_settings.py:7 6155 #: conf/global_settings.py:78 146 156 msgid "Lithuanian" 147 157 msgstr "Lituano" 148 158 149 #: conf/global_settings.py:7 7159 #: conf/global_settings.py:79 150 160 msgid "Latvian" 151 161 msgstr "Letão" 152 162 153 #: conf/global_settings.py: 78163 #: conf/global_settings.py:80 154 164 msgid "Macedonian" 155 165 msgstr "Macedônio" 156 166 157 #: conf/global_settings.py:79 167 #: conf/global_settings.py:81 168 #, fuzzy 169 msgid "Mongolian" 170 msgstr "Monaghan" 171 172 #: conf/global_settings.py:82 158 173 msgid "Dutch" 159 174 msgstr "Neerlandês" 160 175 161 #: conf/global_settings.py:8 0176 #: conf/global_settings.py:83 162 177 msgid "Norwegian" 163 178 msgstr "Norueguês" 164 179 165 #: conf/global_settings.py:81 180 #: conf/global_settings.py:84 181 #, fuzzy 182 msgid "Norwegian Bokmal" 183 msgstr "Norueguês" 184 185 #: conf/global_settings.py:85 186 #, fuzzy 187 msgid "Norwegian Nynorsk" 188 msgstr "Norueguês" 189 190 #: conf/global_settings.py:86 166 191 msgid "Polish" 167 192 msgstr "Polonês" 168 193 169 #: conf/global_settings.py:8 2194 #: conf/global_settings.py:87 170 195 msgid "Portuguese" 171 196 msgstr "Português" 172 197 173 #: conf/global_settings.py:8 3198 #: conf/global_settings.py:88 174 199 msgid "Brazilian Portuguese" 175 200 msgstr "Português Brasileiro" 176 201 177 #: conf/global_settings.py:8 4202 #: conf/global_settings.py:89 178 203 msgid "Romanian" 179 204 msgstr "Romeno" 180 205 181 #: conf/global_settings.py: 85206 #: conf/global_settings.py:90 182 207 msgid "Russian" 183 208 msgstr "Russo" 184 209 185 #: conf/global_settings.py: 86210 #: conf/global_settings.py:91 186 211 msgid "Slovak" 187 212 msgstr "Eslovaco" 188 213 189 #: conf/global_settings.py: 87214 #: conf/global_settings.py:92 190 215 msgid "Slovenian" 191 216 msgstr "Esloveno" 192 217 193 #: conf/global_settings.py: 88218 #: conf/global_settings.py:93 194 219 msgid "Albanian" 195 220 msgstr "Albanesa" 196 221 197 #: conf/global_settings.py: 89222 #: conf/global_settings.py:94 198 223 msgid "Serbian" 199 224 msgstr "Sérvio" 200 225 201 #: conf/global_settings.py:9 0226 #: conf/global_settings.py:95 202 227 msgid "Serbian Latin" 203 228 msgstr "Sérvio Latino" 204 229 205 #: conf/global_settings.py:9 1230 #: conf/global_settings.py:96 206 231 msgid "Swedish" 207 232 msgstr "Sueco" 208 233 209 #: conf/global_settings.py:9 2234 #: conf/global_settings.py:97 210 235 msgid "Tamil" 211 236 msgstr "Tâmil" 212 237 213 #: conf/global_settings.py:9 3238 #: conf/global_settings.py:98 214 239 msgid "Telugu" 215 240 msgstr "Telugu" 216 241 217 #: conf/global_settings.py:9 4242 #: conf/global_settings.py:99 218 243 msgid "Thai" 219 244 msgstr "Tailandês" 220 245 221 #: conf/global_settings.py: 95246 #: conf/global_settings.py:100 222 247 msgid "Turkish" 223 248 msgstr "Turco" 224 249 225 #: conf/global_settings.py: 96250 #: conf/global_settings.py:101 226 251 msgid "Ukrainian" 227 252 msgstr "Ucraniano" 228 253 229 #: conf/global_settings.py: 97254 #: conf/global_settings.py:102 230 255 msgid "Vietnamese" 231 256 msgstr "Vietnamita" 232 257 233 #: conf/global_settings.py: 98258 #: conf/global_settings.py:103 234 259 msgid "Simplified Chinese" 235 260 msgstr "Chinês Simplificado" 236 261 237 #: conf/global_settings.py: 99262 #: conf/global_settings.py:104 238 263 msgid "Traditional Chinese" 239 264 msgstr "Chinês Tradicional" 240 265 241 #: contrib/admin/actions.py: 52266 #: contrib/admin/actions.py:48 242 267 #, python-format 243 268 msgid "Successfully deleted %(count)d %(items)s." 244 269 msgstr "Removido %(count)d %(items)s com sucesso." 245 270 246 #: contrib/admin/actions.py:5 9 contrib/admin/options.py:1101271 #: contrib/admin/actions.py:55 contrib/admin/options.py:1125 247 272 msgid "Are you sure?" 248 273 msgstr "Tem certeza?" 249 274 250 #: contrib/admin/actions.py:7 7275 #: contrib/admin/actions.py:73 251 276 #, python-format 252 277 msgid "Delete selected %(verbose_name_plural)s" 253 278 msgstr "Remover %(verbose_name_plural)s selecionados" … … msgstr "Este mês" 286 311 msgid "This year" 287 312 msgstr "Este ano" 288 313 289 #: contrib/admin/filterspecs.py:147 forms/widgets.py:4 70314 #: contrib/admin/filterspecs.py:147 forms/widgets.py:466 290 315 msgid "Yes" 291 316 msgstr "Sim" 292 317 293 #: contrib/admin/filterspecs.py:147 forms/widgets.py:4 70318 #: contrib/admin/filterspecs.py:147 forms/widgets.py:466 294 319 msgid "No" 295 320 msgstr "Não" 296 321 297 #: contrib/admin/filterspecs.py:154 forms/widgets.py:4 70322 #: contrib/admin/filterspecs.py:154 forms/widgets.py:466 298 323 msgid "Unknown" 299 324 msgstr "Desconhecido" 300 325 301 #: contrib/admin/helpers.py: 19326 #: contrib/admin/helpers.py:20 302 327 msgid "Action:" 303 328 msgstr "Ação:" 304 329 … … msgstr "entrada de log" 330 355 msgid "log entries" 331 356 msgstr "entradas de log" 332 357 333 #: contrib/admin/options.py:13 9 contrib/admin/options.py:154358 #: contrib/admin/options.py:138 contrib/admin/options.py:153 334 359 msgid "None" 335 360 msgstr "Nenhum" 336 361 337 #: contrib/admin/options.py:55 8362 #: contrib/admin/options.py:559 338 363 #, python-format 339 364 msgid "Changed %s." 340 365 msgstr "Modificado %s." 341 366 342 #: contrib/admin/options.py:55 8 contrib/admin/options.py:568343 #: contrib/comments/templates/comments/preview.html:16 db/models/base.py:84 0344 #: forms/models.py:5 56367 #: 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 345 370 msgid "and" 346 371 msgstr "e" 347 372 348 #: contrib/admin/options.py:56 3373 #: contrib/admin/options.py:564 349 374 #, python-format 350 375 msgid "Added %(name)s \"%(object)s\"." 351 376 msgstr "Adicionado %(name)s \"%(object)s\"" 352 377 353 #: contrib/admin/options.py:56 7378 #: contrib/admin/options.py:568 354 379 #, python-format 355 380 msgid "Changed %(list)s for %(name)s \"%(object)s\"." 356 381 msgstr "Modificado %(list)s para %(name)s \"%(object)s\"." 357 382 358 #: contrib/admin/options.py:57 2383 #: contrib/admin/options.py:573 359 384 #, python-format 360 385 msgid "Deleted %(name)s \"%(object)s\"." 361 386 msgstr "Deletado %(name)s \"%(object)s\"." 362 387 363 #: contrib/admin/options.py:57 6388 #: contrib/admin/options.py:577 364 389 msgid "No fields changed." 365 390 msgstr "Nenhum campo modificado." 366 391 367 #: contrib/admin/options.py:64 2392 #: contrib/admin/options.py:643 368 393 #, python-format 369 394 msgid "The %(name)s \"%(obj)s\" was added successfully." 370 395 msgstr "%(name)s \"%(obj)s\": adicionado com sucesso." 371 396 372 #: contrib/admin/options.py:64 6 contrib/admin/options.py:679397 #: contrib/admin/options.py:647 contrib/admin/options.py:680 373 398 msgid "You may edit it again below." 374 399 msgstr "Você pode editar novamente abaixo." 375 400 376 #: contrib/admin/options.py:65 6 contrib/admin/options.py:689401 #: contrib/admin/options.py:657 contrib/admin/options.py:690 377 402 #, python-format 378 403 msgid "You may add another %s below." 379 404 msgstr "Você pode adicionar outro %s abaixo." 380 405 381 #: contrib/admin/options.py:67 7406 #: contrib/admin/options.py:678 382 407 #, python-format 383 408 msgid "The %(name)s \"%(obj)s\" was changed successfully." 384 409 msgstr "%(name)s \"%(obj)s\": modificado com sucesso." 385 410 386 #: contrib/admin/options.py:68 5411 #: contrib/admin/options.py:686 387 412 #, python-format 388 413 msgid "" 389 414 "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below." … … msgstr "" 391 416 "%(name)s \"%(obj)s\": adicionado com sucesso. Você pode editar novamente " 392 417 "abaixo." 393 418 394 #: contrib/admin/options.py:74 3419 #: contrib/admin/options.py:740 contrib/admin/options.py:997 395 420 msgid "" 396 421 "Items must be selected in order to perform actions on them. No items have " 397 422 "been changed." … … msgstr "" 399 424 "Os itens devem ser selecionados a fim de executar ações sobre eles. Nenhum " 400 425 "item foi modificado." 401 426 402 #: contrib/admin/options.py:7 61427 #: contrib/admin/options.py:759 403 428 msgid "No action selected." 404 429 msgstr "Nenhuma ação selecionada." 405 430 406 #: contrib/admin/options.py:84 1431 #: contrib/admin/options.py:840 407 432 #, python-format 408 433 msgid "Add %s" 409 434 msgstr "Adicionar %s" 410 435 411 #: contrib/admin/options.py:86 7 contrib/admin/options.py:1081436 #: contrib/admin/options.py:866 contrib/admin/options.py:1105 412 437 #, python-format 413 438 msgid "%(name)s object with primary key %(key)r does not exist." 414 439 msgstr "Objeto %(name)s com chave primária %(key)r não existe." 415 440 416 #: contrib/admin/options.py:93 2441 #: contrib/admin/options.py:931 417 442 #, python-format 418 443 msgid "Change %s" 419 444 msgstr "Modificar %s" … … msgstr "Modificar %s" 422 447 msgid "Database error" 423 448 msgstr "Erro no banco de dados" 424 449 425 #: contrib/admin/options.py:10 13450 #: contrib/admin/options.py:1039 426 451 #, python-format 427 452 msgid "%(count)s %(name)s was changed successfully." 428 453 msgid_plural "%(count)s %(name)s were changed successfully." 429 454 msgstr[0] "%(count)s %(name)s modificado com sucesso." 430 455 msgstr[1] "%(count)s %(name)s modificados com sucesso." 431 456 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 440 458 #, python-format 441 459 msgid "%(total_count)s selected" 442 460 msgid_plural "All %(total_count)s selected" 443 461 msgstr[0] "%(total_count)s selecionado" 444 462 msgstr[1] "Todos %(total_count)s selecionados" 445 463 446 #: contrib/admin/options.py:1094 464 #: contrib/admin/options.py:1071 465 #, fuzzy, python-format 466 msgid "0 of %(cnt)s selected" 467 msgstr "de %(count)d selecionado" 468 469 #: contrib/admin/options.py:1118 447 470 #, python-format 448 471 msgid "The %(name)s \"%(obj)s\" was deleted successfully." 449 472 msgstr "%(name)s \"%(obj)s\": excluído com sucesso." 450 473 451 #: contrib/admin/options.py:11 31474 #: contrib/admin/options.py:1155 452 475 #, python-format 453 476 msgid "Change history: %s" 454 477 msgstr "Histórico de modificações: %s" 455 478 456 #: contrib/admin/sites.py: 22contrib/admin/views/decorators.py:14479 #: contrib/admin/sites.py:18 contrib/admin/views/decorators.py:14 457 480 #: contrib/auth/forms.py:81 458 481 msgid "" 459 482 "Please enter a correct username and password. Note that both fields are case-" … … msgstr "" 462 485 "Por favor, entre com um usuário e senha corretos. Note que ambos os campos " 463 486 "diferenciam maiúsculas e minúsculas." 464 487 465 #: contrib/admin/sites.py:3 11contrib/admin/views/decorators.py:40488 #: contrib/admin/sites.py:307 contrib/admin/views/decorators.py:40 466 489 msgid "Please log in again, because your session has expired." 467 490 msgstr "Por favor acesse novamente, pois sua sessão expirou." 468 491 469 #: contrib/admin/sites.py:31 8contrib/admin/views/decorators.py:47492 #: contrib/admin/sites.py:314 contrib/admin/views/decorators.py:47 470 493 msgid "" 471 494 "Looks like your browser isn't configured to accept cookies. Please enable " 472 495 "cookies, reload this page, and try again." … … msgstr "" 474 497 "Parece que seu navegador não está configurado para aceitar cookies. Por " 475 498 "favor habilite os cookies, recarregue esta página, e tente novamente." 476 499 477 #: contrib/admin/sites.py:33 4 contrib/admin/sites.py:340500 #: contrib/admin/sites.py:330 contrib/admin/sites.py:336 478 501 #: contrib/admin/views/decorators.py:66 479 502 msgid "Usernames cannot contain the '@' character." 480 503 msgstr "Nomes de usuário não podem conter o caractere '@'." 481 504 482 #: contrib/admin/sites.py:33 7contrib/admin/views/decorators.py:62505 #: contrib/admin/sites.py:333 contrib/admin/views/decorators.py:62 483 506 #, python-format 484 507 msgid "Your e-mail address is not your username. Try '%s' instead." 485 508 msgstr "Seu endereço de e-mail não é seu nome de usuário. Tente usar '%s'" 486 509 487 #: contrib/admin/sites.py:3 93510 #: contrib/admin/sites.py:389 488 511 msgid "Site administration" 489 512 msgstr "Administração do Site" 490 513 491 #: contrib/admin/sites.py:40 7contrib/admin/templates/admin/login.html:26514 #: contrib/admin/sites.py:403 contrib/admin/templates/admin/login.html:26 492 515 #: contrib/admin/templates/registration/password_reset_complete.html:14 493 516 #: contrib/admin/views/decorators.py:20 494 517 msgid "Log in" 495 518 msgstr "Acessar" 496 519 497 #: contrib/admin/sites.py:4 52520 #: contrib/admin/sites.py:448 498 521 #, python-format 499 522 msgid "%s administration" 500 523 msgstr "Administração de %s" … … msgstr "Desculpe, mas a página requisitada não pode ser encontrada." 534 557 535 558 #: contrib/admin/templates/admin/500.html:4 536 559 #: contrib/admin/templates/admin/app_index.html:8 537 #: contrib/admin/templates/admin/base.html:5 4560 #: contrib/admin/templates/admin/base.html:55 538 561 #: contrib/admin/templates/admin/change_form.html:18 539 #: contrib/admin/templates/admin/change_list.html: 39562 #: contrib/admin/templates/admin/change_list.html:42 540 563 #: contrib/admin/templates/admin/delete_confirmation.html:6 541 564 #: contrib/admin/templates/admin/delete_selected_confirmation.html:6 542 565 #: contrib/admin/templates/admin/invalid_setup.html:4 … … msgstr "Executar ação selecionada" 581 604 msgid "Go" 582 605 msgstr "Ir" 583 606 584 #: contrib/admin/templates/admin/actions.html:1 0607 #: contrib/admin/templates/admin/actions.html:11 585 608 msgid "Click here to select the objects across all pages" 586 609 msgstr "Clique aqui para selecionar os objetos de todas as páginas" 587 610 588 #: contrib/admin/templates/admin/actions.html:1 0611 #: contrib/admin/templates/admin/actions.html:11 589 612 #, python-format 590 613 msgid "Select all %(total_count)s %(module_name)s" 591 614 msgstr "Selecionar todos %(total_count)s %(module_name)s" 592 615 593 #: contrib/admin/templates/admin/actions.html:1 2616 #: contrib/admin/templates/admin/actions.html:13 594 617 msgid "Clear selection" 595 618 msgstr "Limpar seleção" 596 619 … … msgstr "Limpar seleção" 600 623 msgid "%(name)s" 601 624 msgstr "%(name)s" 602 625 603 #: contrib/admin/templates/admin/base.html:2 7626 #: contrib/admin/templates/admin/base.html:28 604 627 msgid "Welcome," 605 628 msgstr "Bem vindo," 606 629 607 #: contrib/admin/templates/admin/base.html:3 2630 #: contrib/admin/templates/admin/base.html:33 608 631 #: contrib/admin/templates/registration/password_change_done.html:3 609 632 #: contrib/admin/templates/registration/password_change_form.html:4 610 633 #: contrib/admindocs/templates/admin_doc/bookmarklets.html:3 611 634 msgid "Documentation" 612 635 msgstr "Documentação" 613 636 614 #: contrib/admin/templates/admin/base.html:4 0637 #: contrib/admin/templates/admin/base.html:41 615 638 #: contrib/admin/templates/admin/auth/user/change_password.html:15 616 639 #: contrib/admin/templates/admin/auth/user/change_password.html:48 617 640 #: contrib/admin/templates/registration/password_change_done.html:3 … … msgstr "Documentação" 619 642 msgid "Change password" 620 643 msgstr "Alterar senha" 621 644 622 #: contrib/admin/templates/admin/base.html:4 7645 #: contrib/admin/templates/admin/base.html:48 623 646 #: contrib/admin/templates/registration/password_change_done.html:3 624 647 #: contrib/admin/templates/registration/password_change_form.html:4 625 648 msgid "Log out" … … msgid "View on site" 650 673 msgstr "Ver no site" 651 674 652 675 #: contrib/admin/templates/admin/change_form.html:39 653 #: contrib/admin/templates/admin/change_list.html: 68676 #: contrib/admin/templates/admin/change_list.html:71 654 677 #: contrib/admin/templates/admin/auth/user/change_password.html:24 655 678 #: contrib/admin/templates/registration/password_change_form.html:15 656 679 msgid "Please correct the error below." … … msgid_plural "Please correct the errors below." 658 681 msgstr[0] "Por favor, corrija o erro abaixo." 659 682 msgstr[1] "Por favor, corrija os erros abaixo." 660 683 661 #: contrib/admin/templates/admin/change_list.html:6 0684 #: contrib/admin/templates/admin/change_list.html:63 662 685 #, python-format 663 686 msgid "Add %(name)s" 664 687 msgstr "Adicionar %(name)s" 665 688 666 #: contrib/admin/templates/admin/change_list.html: 79689 #: contrib/admin/templates/admin/change_list.html:82 667 690 msgid "Filter" 668 691 msgstr "Filtro" 669 692 670 693 #: contrib/admin/templates/admin/delete_confirmation.html:10 671 #: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py: 297694 #: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py:302 672 695 msgid "Delete" 673 696 msgstr "Apagar" 674 697 … … msgstr "Senha (novamente)" 859 882 msgid "Enter the same password as above, for verification." 860 883 msgstr "Informe a mesma senha digitada acima, para verificação." 861 884 862 #: contrib/admin/templates/admin/edit_inline/stacked.html: 53863 #: contrib/admin/templates/admin/edit_inline/tabular.html: 99885 #: contrib/admin/templates/admin/edit_inline/stacked.html:64 886 #: contrib/admin/templates/admin/edit_inline/tabular.html:110 864 887 #, python-format 865 888 msgid "Add another %(verbose_name)s" 866 889 msgstr "Adicionar outro %(verbose_name)s" 867 890 868 #: contrib/admin/templates/admin/edit_inline/stacked.html: 56869 #: contrib/admin/templates/admin/edit_inline/tabular.html:1 02891 #: contrib/admin/templates/admin/edit_inline/stacked.html:67 892 #: contrib/admin/templates/admin/edit_inline/tabular.html:113 870 893 #: contrib/comments/templates/comments/delete.html:12 871 894 msgid "Remove" 872 895 msgstr "Remover" … … msgstr "Endereço de e-mail:" 1031 1054 msgid "Reset my password" 1032 1055 msgstr "Reinicializar minha senha" 1033 1056 1034 #: contrib/admin/templatetags/admin_list.py:2 401057 #: contrib/admin/templatetags/admin_list.py:257 1035 1058 msgid "All dates" 1036 1059 msgstr "Todas as datas" 1037 1060 1038 #: contrib/admin/views/main.py: 701061 #: contrib/admin/views/main.py:65 1039 1062 #, python-format 1040 1063 msgid "Select %s" 1041 1064 msgstr "Selecione %s" 1042 1065 1043 #: contrib/admin/views/main.py: 701066 #: contrib/admin/views/main.py:65 1044 1067 #, python-format 1045 1068 msgid "Select %s to change" 1046 1069 msgstr "Selecione %s para modificar" … … msgstr "Usuário" 1210 1233 1211 1234 #: contrib/auth/forms.py:15 contrib/auth/forms.py:49 1212 1235 msgid "Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only." 1213 msgstr "Obrigatório. 30 caracteres ou menos. Somente letras, dígitos e @/./+/-/_." 1236 msgstr "" 1237 "Obrigatório. 30 caracteres ou menos. Somente letras, dígitos e @/./+/-/_." 1214 1238 1215 1239 #: contrib/auth/forms.py:16 contrib/auth/forms.py:50 1216 1240 msgid "This value may contain only letters, numbers and @/./+/-/_ characters." 1217 msgstr "Este valor deve conter apenas letras, números e os caracteres @/./+/-/_." 1241 msgstr "" 1242 "Este valor deve conter apenas letras, números e os caracteres @/./+/-/_." 1218 1243 1219 1244 #: contrib/auth/forms.py:18 1220 1245 msgid "Password confirmation" … … msgstr "usuário" 1299 1324 #: contrib/auth/models.py:196 1300 1325 msgid "" 1301 1326 "Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters" 1302 msgstr "Obrigatório. 30 caracteres ou menos. Letras, números e os caracteres @/./+/-/_" 1327 msgstr "" 1328 "Obrigatório. 30 caracteres ou menos. Letras, números e os caracteres @/./+/-/" 1329 "_" 1303 1330 1304 1331 #: contrib/auth/models.py:197 1305 1332 msgid "first name" … … msgstr "mensagem" 1393 1420 msgid "Logged out" 1394 1421 msgstr "Sessão encerrada" 1395 1422 1396 #: contrib/auth/management/commands/createsuperuser.py:2 31397 #: core/validators.py:120 forms/fields.py:4 161423 #: contrib/auth/management/commands/createsuperuser.py:24 1424 #: core/validators.py:120 forms/fields.py:427 1398 1425 msgid "Enter a valid e-mail address." 1399 1426 msgstr "Informe um endereço de email válido." 1400 1427 … … msgid "Email address" 1462 1489 msgstr "Endereço de e-mail" 1463 1490 1464 1491 #: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8 1465 #: contrib/flatpages/models.py:7 db/models/fields/__init__.py:11 211492 #: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1101 1466 1493 msgid "URL" 1467 1494 msgstr "URL" 1468 1495 … … msgstr "comentário" 1513 1540 msgid "date/time submitted" 1514 1541 msgstr "data/hora de envio" 1515 1542 1516 #: contrib/comments/models.py:60 db/models/fields/__init__.py: 9161543 #: contrib/comments/models.py:60 db/models/fields/__init__.py:896 1517 1544 msgid "IP address" 1518 1545 msgstr "Endereço IP" 1519 1546 … … msgstr "" 1759 1786 msgid "The base GIS field -- maps to the OpenGIS Specification Geometry type." 1760 1787 msgstr "" 1761 1788 1762 #: contrib/gis/db/models/fields.py:2 691789 #: contrib/gis/db/models/fields.py:270 1763 1790 msgid "Point" 1764 1791 msgstr "Ponto" 1765 1792 1766 #: contrib/gis/db/models/fields.py:27 31793 #: contrib/gis/db/models/fields.py:274 1767 1794 msgid "Line string" 1768 1795 msgstr "Linha string" 1769 1796 1770 #: contrib/gis/db/models/fields.py:27 71797 #: contrib/gis/db/models/fields.py:278 1771 1798 msgid "Polygon" 1772 1799 msgstr "Polígono" 1773 1800 1774 #: contrib/gis/db/models/fields.py:28 11801 #: contrib/gis/db/models/fields.py:282 1775 1802 msgid "Multi-point" 1776 1803 msgstr "Multiponto" 1777 1804 1778 #: contrib/gis/db/models/fields.py:28 51805 #: contrib/gis/db/models/fields.py:286 1779 1806 msgid "Multi-line string" 1780 1807 msgstr "Multilinha string" 1781 1808 1782 #: contrib/gis/db/models/fields.py:2 891809 #: contrib/gis/db/models/fields.py:290 1783 1810 msgid "Multi polygon" 1784 1811 msgstr "Multipolígono" 1785 1812 1786 #: contrib/gis/db/models/fields.py:29 31813 #: contrib/gis/db/models/fields.py:294 1787 1814 msgid "Geometry collection" 1788 1815 msgstr "Coleção geométrica" 1789 1816 … … msgstr "ontem" 1896 1923 msgid "Enter a postal code in the format NNNN or ANNNNAAA." 1897 1924 msgstr "Informe um código postal no formato NNNN ou ANNNNAAA." 1898 1925 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 1902 1928 msgid "This field requires only numbers." 1903 1929 msgstr "Este campo requer somente números." 1904 1930 … … msgstr "" 1964 1990 msgid "Enter a 4 digit post code." 1965 1991 msgstr "Informe um código postal de 4 dígitos." 1966 1992 1967 #: contrib/localflavor/br/forms.py:22 1993 #: contrib/localflavor/br/br_cpfcnpj.py:34 1994 msgid "Invalid CNPJ number." 1995 msgstr "Número de CNPJ inválido." 1996 1997 #: contrib/localflavor/br/br_cpfcnpj.py:35 1998 msgid "CNPJ requires at most 14 digits or 18 characters." 1999 msgstr "Este campo requer no máximo 14 dígitos ou 18 caracteres." 2000 2001 #: contrib/localflavor/br/br_cpfcnpj.py:36 2002 msgid "CNPJ requires only numbers, allow '.', '/' and '-' for long format." 2003 msgstr "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 2006 msgid "Invalid CPF number." 2007 msgstr "Número de CPF inválido." 2008 2009 #: contrib/localflavor/br/br_cpfcnpj.py:202 2010 msgid "CPF requires at most 11 digits or 14 characters." 2011 msgstr "Este campo requer no máximo 11 dígitos ou 14 caracteres." 2012 2013 #: contrib/localflavor/br/br_cpfcnpj.py:203 2014 msgid "CPF requires only numbers, allow '.' and '-' for long format." 2015 msgstr "Este campo aceita somente números e os caracteres '.' e '-'." 2016 2017 #: contrib/localflavor/br/forms.py:18 1968 2018 msgid "Enter a zip code in the format XXXXX-XXX." 1969 2019 msgstr "Informe um código postal no formato XXXXX-XXX." 1970 2020 1971 #: contrib/localflavor/br/forms.py: 312021 #: contrib/localflavor/br/forms.py:27 1972 2022 msgid "Phone numbers must be in XX-XXXX-XXXX format." 1973 2023 msgstr "Números de telefone devem estar no formato XX-XXXX-XXXX." 1974 2024 1975 #: contrib/localflavor/br/forms.py:5 92025 #: contrib/localflavor/br/forms.py:55 1976 2026 msgid "" 1977 2027 "Select a valid brazilian state. That state is not one of the available " 1978 2028 "states." … … msgstr "" 1980 2030 "Selecione um estado brasileiro válido. O estado escolhido não é um dos " 1981 2031 "estados disponíveis." 1982 2032 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 1988 2034 msgid "This field requires at most 11 digits or 14 characters." 1989 2035 msgstr "Este campo requer no máximo 11 dígitos ou 14 caracteres." 1990 2036 1991 #: contrib/localflavor/br/forms.py:1351992 msgid "Invalid CNPJ number."1993 msgstr "Número de CNPJ inválido."1994 1995 #: contrib/localflavor/br/forms.py:1371996 msgid "This field requires at least 14 digits"1997 msgstr "Este campo requer ao menos 14 dígitos"1998 1999 2037 #: contrib/localflavor/ca/forms.py:25 2000 2038 msgid "Enter a postal code in the format XXX XXX." 2001 2039 msgstr "Informe um código postal no formato XXX XXX." … … msgstr "sites" 4452 4490 msgid "Enter a valid value." 4453 4491 msgstr "Informe um valor válido." 4454 4492 4455 #: core/validators.py:87 forms/fields.py:5 174493 #: core/validators.py:87 forms/fields.py:528 4456 4494 msgid "Enter a valid URL." 4457 4495 msgstr "Informe uma URL válida." 4458 4496 4459 #: core/validators.py:89 forms/fields.py:5 184497 #: core/validators.py:89 forms/fields.py:529 4460 4498 msgid "This URL appears to be a broken link." 4461 4499 msgstr "A URL %s aparenta ser um link quebrado." 4462 4500 4463 #: core/validators.py:123 forms/fields.py:8 614501 #: core/validators.py:123 forms/fields.py:877 4464 4502 msgid "" 4465 4503 "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens." 4466 4504 msgstr "" 4467 4505 "Insira um \"slug\" válido consistindo de letras, números, sublinhados (_) ou " 4468 4506 "hífens." 4469 4507 4470 #: core/validators.py:126 forms/fields.py:8 544508 #: core/validators.py:126 forms/fields.py:870 4471 4509 msgid "Enter a valid IPv4 address." 4472 4510 msgstr "Informe um endereço IPv4 válido." 4473 4511 4474 #: core/validators.py:129 db/models/fields/__init__.py:5 984512 #: core/validators.py:129 db/models/fields/__init__.py:572 4475 4513 msgid "Enter only digits separated by commas." 4476 4514 msgstr "Informe apenas dígitos separados por vírgulas." 4477 4515 … … msgstr "Informe apenas dígitos separados por vírgulas." 4480 4518 msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)." 4481 4519 msgstr "Certifique-se de que o valor é %(limit_value)s (ele é %(show_value)s)." 4482 4520 4483 #: core/validators.py:153 forms/fields.py: 196 forms/fields.py:2464521 #: core/validators.py:153 forms/fields.py:204 forms/fields.py:256 4484 4522 #, python-format 4485 4523 msgid "Ensure this value is less than or equal to %(limit_value)s." 4486 4524 msgstr "Certifique-se que este valor seja menor ou igual a %(limit_value)s." 4487 4525 4488 #: core/validators.py:158 forms/fields.py: 197 forms/fields.py:2474526 #: core/validators.py:158 forms/fields.py:205 forms/fields.py:257 4489 4527 #, python-format 4490 4528 msgid "Ensure this value is greater than or equal to %(limit_value)s." 4491 4529 msgstr "Certifique-se que este valor seja maior ou igual a %(limit_value)s." … … msgstr "" 4508 4546 "Certifique-se de que o valor tenha no máximo %(limit_value)d caracteres (ele " 4509 4547 "possui %(show_value)d)." 4510 4548 4511 #: db/models/base.py:8 184549 #: db/models/base.py:823 4512 4550 #, python-format 4513 4551 msgid "%(field_name)s must be unique for %(date_field)s %(lookup)s." 4514 4552 msgstr "%(field_name)s deverá ser único para %(date_field)s %(lookup)s." 4515 4553 4516 #: db/models/base.py:83 3 db/models/base.py:8414554 #: db/models/base.py:838 db/models/base.py:846 4517 4555 #, python-format 4518 4556 msgid "%(model_name)s with this %(field_label)s already exists." 4519 4557 msgstr "%(model_name)s com este %(field_label)s já existe." 4520 4558 4521 #: db/models/fields/__init__.py:6 24559 #: db/models/fields/__init__.py:63 4522 4560 #, python-format 4523 4561 msgid "Value %r is not a valid choice." 4524 4562 msgstr "O valor %r não é uma escolha válida." 4525 4563 4526 #: db/models/fields/__init__.py:6 34564 #: db/models/fields/__init__.py:64 4527 4565 msgid "This field cannot be null." 4528 4566 msgstr "Este campo não pode ser nulo." 4529 4567 4530 #: db/models/fields/__init__.py:6 44568 #: db/models/fields/__init__.py:65 4531 4569 msgid "This field cannot be blank." 4532 4570 msgstr "Este campo não pode estar em branco." 4533 4571 4534 #: db/models/fields/__init__.py: 694572 #: db/models/fields/__init__.py:70 4535 4573 #, python-format 4536 4574 msgid "Field of type: %(field_type)s" 4537 4575 msgstr "Campo do tipo: %(field_type)s" 4538 4576 4539 #: db/models/fields/__init__.py:4 77 db/models/fields/__init__.py:8784540 #: db/models/fields/__init__.py:9 81 db/models/fields/__init__.py:9924541 #: db/models/fields/__init__.py: 10194577 #: 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 4542 4580 msgid "Integer" 4543 4581 msgstr "Inteiro" 4544 4582 4545 #: db/models/fields/__init__.py:4 81 db/models/fields/__init__.py:8764583 #: db/models/fields/__init__.py:455 db/models/fields/__init__.py:850 4546 4584 msgid "This value must be an integer." 4547 4585 msgstr "Este valor deve ser um inteiro." 4548 4586 4549 #: db/models/fields/__init__.py: 5164587 #: db/models/fields/__init__.py:490 4550 4588 msgid "This value must be either True or False." 4551 4589 msgstr "Este valor deve ser True ou False." 4552 4590 4553 #: db/models/fields/__init__.py: 5184591 #: db/models/fields/__init__.py:492 4554 4592 msgid "Boolean (Either True or False)" 4555 4593 msgstr "Booleano (Verdadeiro ou Falso)" 4556 4594 4557 #: db/models/fields/__init__.py:5 65 db/models/fields/__init__.py:10024595 #: db/models/fields/__init__.py:539 db/models/fields/__init__.py:982 4558 4596 #, python-format 4559 4597 msgid "String (up to %(max_length)s)" 4560 4598 msgstr "String (até %(max_length)s)" 4561 4599 4562 #: db/models/fields/__init__.py:5 934600 #: db/models/fields/__init__.py:567 4563 4601 msgid "Comma-separated integers" 4564 4602 msgstr "Inteiros separados por vírgula" 4565 4603 4566 #: db/models/fields/__init__.py: 6074604 #: db/models/fields/__init__.py:581 4567 4605 msgid "Date (without time)" 4568 4606 msgstr "Data (sem hora)" 4569 4607 4570 #: db/models/fields/__init__.py: 6114608 #: db/models/fields/__init__.py:585 4571 4609 msgid "Enter a valid date in YYYY-MM-DD format." 4572 4610 msgstr "Informe uma data válida no formato AAAA-MM-DD." 4573 4611 4574 #: db/models/fields/__init__.py: 6124612 #: db/models/fields/__init__.py:586 4575 4613 #, python-format 4576 4614 msgid "Invalid date: %s" 4577 4615 msgstr "Data inválida: %s" 4578 4616 4579 #: db/models/fields/__init__.py:6 934617 #: db/models/fields/__init__.py:667 4580 4618 msgid "Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format." 4581 4619 msgstr "" 4582 4620 "Informe uma data/hora válida no formato YYYY-MM-DD HH:MM[:ss[.uuuuuu]]." 4583 4621 4584 #: db/models/fields/__init__.py:6 954622 #: db/models/fields/__init__.py:669 4585 4623 msgid "Date (with time)" 4586 4624 msgstr "Data e hora" 4587 4625 4588 #: db/models/fields/__init__.py:7 614626 #: db/models/fields/__init__.py:735 4589 4627 msgid "This value must be a decimal number." 4590 4628 msgstr "Este valor deve ser um número decimal." 4591 4629 4592 #: db/models/fields/__init__.py:7 634630 #: db/models/fields/__init__.py:737 4593 4631 msgid "Decimal number" 4594 4632 msgstr "Número decimal" 4595 4633 4596 #: db/models/fields/__init__.py: 8184634 #: db/models/fields/__init__.py:792 4597 4635 msgid "E-mail address" 4598 4636 msgstr "Endereço de e-mail" 4599 4637 4600 #: db/models/fields/__init__.py: 825db/models/fields/files.py:2204638 #: db/models/fields/__init__.py:799 db/models/fields/files.py:220 4601 4639 #: db/models/fields/files.py:331 4602 4640 msgid "File path" 4603 4641 msgstr "Caminho de arquivo" 4604 4642 4605 #: db/models/fields/__init__.py:8 484643 #: db/models/fields/__init__.py:822 4606 4644 msgid "This value must be a float." 4607 4645 msgstr "Este valor deve ser um ponto flutuante." 4608 4646 4609 #: db/models/fields/__init__.py:8 504647 #: db/models/fields/__init__.py:824 4610 4648 msgid "Floating point number" 4611 4649 msgstr "Número de ponto flutuante" 4612 4650 4613 #: db/models/fields/__init__.py: 9034651 #: db/models/fields/__init__.py:883 4614 4652 msgid "Big (8 byte) integer" 4615 4653 msgstr "Inteiro grande (8 byte)" 4616 4654 4617 #: db/models/fields/__init__.py:9 324655 #: db/models/fields/__init__.py:912 4618 4656 msgid "This value must be either None, True or False." 4619 4657 msgstr "Este valor deve ser None, True ou False." 4620 4658 4621 #: db/models/fields/__init__.py:9 344659 #: db/models/fields/__init__.py:914 4622 4660 msgid "Boolean (Either True, False or None)" 4623 4661 msgstr "Booleano (Verdadeiro, Falso ou Nada)" 4624 4662 4625 #: db/models/fields/__init__.py:10 254663 #: db/models/fields/__init__.py:1005 4626 4664 msgid "Text" 4627 4665 msgstr "Texto" 4628 4666 4629 #: db/models/fields/__init__.py:10 414667 #: db/models/fields/__init__.py:1021 4630 4668 msgid "Time" 4631 4669 msgstr "Hora" 4632 4670 4633 #: db/models/fields/__init__.py:10 454671 #: db/models/fields/__init__.py:1025 4634 4672 msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format." 4635 4673 msgstr "Informe uma hora válida no formato HH:MM[:ss[.uuuuuu]]." 4636 4674 4637 #: db/models/fields/__init__.py:11 294675 #: db/models/fields/__init__.py:1109 4638 4676 msgid "XML text" 4639 4677 msgstr "Texto XML" 4640 4678 4641 #: db/models/fields/related.py:7 554679 #: db/models/fields/related.py:799 4642 4680 #, python-format 4643 4681 msgid "Model %(model)s with pk %(pk)r does not exist." 4644 4682 msgstr "Model %(model)s com chave primária %(pk)r não existe." 4645 4683 4646 #: db/models/fields/related.py: 7574684 #: db/models/fields/related.py:801 4647 4685 msgid "Foreign Key (type determined by related field)" 4648 4686 msgstr "Chave Estrangeira (tipo determinado pelo campo relacionado)" 4649 4687 4650 #: db/models/fields/related.py: 8794688 #: db/models/fields/related.py:918 4651 4689 msgid "One-to-one relationship" 4652 4690 msgstr "Relacionamento um-para-um" 4653 4691 4654 #: db/models/fields/related.py:9 394692 #: db/models/fields/related.py:980 4655 4693 msgid "Many-to-many relationship" 4656 4694 msgstr "Relacionamento muitos-para-muitos" 4657 4695 4658 #: db/models/fields/related.py: 9594696 #: db/models/fields/related.py:1000 4659 4697 msgid "" 4660 4698 "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." 4661 4699 msgstr "" 4662 4700 "Mantenha pressionado \"Control\" (ou \"Command\" no Mac) para selecionar " 4663 4701 "mais de uma opção." 4664 4702 4665 #: db/models/fields/related.py:10 204703 #: db/models/fields/related.py:1061 4666 4704 #, python-format 4667 4705 msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid." 4668 4706 msgid_plural "" … … msgstr[1] "" 4677 4715 msgid "This field is required." 4678 4716 msgstr "Este campo é obrigatório." 4679 4717 4680 #: forms/fields.py: 1954718 #: forms/fields.py:203 4681 4719 msgid "Enter a whole number." 4682 4720 msgstr "Informe um número inteiro." 4683 4721 4684 #: forms/fields.py:2 25 forms/fields.py:2454722 #: forms/fields.py:234 forms/fields.py:255 4685 4723 msgid "Enter a number." 4686 4724 msgstr "Informe um número." 4687 4725 4688 #: forms/fields.py:2 484726 #: forms/fields.py:258 4689 4727 #, python-format 4690 4728 msgid "Ensure that there are no more than %s digits in total." 4691 4729 msgstr "Certifique-se de que não tenha mais de %s dígitos no total." 4692 4730 4693 #: forms/fields.py:2 494731 #: forms/fields.py:259 4694 4732 #, python-format 4695 4733 msgid "Ensure that there are no more than %s decimal places." 4696 4734 msgstr "Certifique-se de que não tenha mais de %s casa decimais." 4697 4735 4698 #: forms/fields.py:2 504736 #: forms/fields.py:260 4699 4737 #, python-format 4700 4738 msgid "Ensure that there are no more than %s digits before the decimal point." 4701 4739 msgstr "" 4702 4740 "Certifique-se de que não tenha mais de %s dígitos antes do ponto decimal." 4703 4741 4704 #: forms/fields.py:3 11 forms/fields.py:8264742 #: forms/fields.py:322 forms/fields.py:837 4705 4743 msgid "Enter a valid date." 4706 4744 msgstr "Informe uma data válida." 4707 4745 4708 #: forms/fields.py:3 39 forms/fields.py:8274746 #: forms/fields.py:350 forms/fields.py:838 4709 4747 msgid "Enter a valid time." 4710 4748 msgstr "Informe uma hora válida." 4711 4749 4712 #: forms/fields.py:3 654750 #: forms/fields.py:376 4713 4751 msgid "Enter a valid date/time." 4714 4752 msgstr "Informe uma data/hora válida." 4715 4753 4716 #: forms/fields.py:4 234754 #: forms/fields.py:434 4717 4755 msgid "No file was submitted. Check the encoding type on the form." 4718 4756 msgstr "Nenhum arquivo enviado. Verifique o tipo de codificação do formulário." 4719 4757 4720 #: forms/fields.py:4 244758 #: forms/fields.py:435 4721 4759 msgid "No file was submitted." 4722 4760 msgstr "Não foi enviado nenhum arquivo." 4723 4761 4724 #: forms/fields.py:4 254762 #: forms/fields.py:436 4725 4763 msgid "The submitted file is empty." 4726 4764 msgstr "O arquivo enviado está vazio." 4727 4765 4728 #: forms/fields.py:4 264766 #: forms/fields.py:437 4729 4767 #, python-format 4730 4768 msgid "" 4731 4769 "Ensure this filename has at most %(max)d characters (it has %(length)d)." … … msgstr "" 4733 4771 "Certifique-se de que o arquivo tenha no máximo %(max)d caracteres (ele " 4734 4772 "possui %(length)d)." 4735 4773 4736 #: forms/fields.py:4 614774 #: forms/fields.py:472 4737 4775 msgid "" 4738 4776 "Upload a valid image. The file you uploaded was either not an image or a " 4739 4777 "corrupted image." … … msgstr "" 4741 4779 "Envie uma imagem válida. O arquivo enviado não é uma imagem ou está " 4742 4780 "corrompido." 4743 4781 4744 #: forms/fields.py:5 84 forms/fields.py:6594782 #: forms/fields.py:595 forms/fields.py:670 4745 4783 #, python-format 4746 4784 msgid "Select a valid choice. %(value)s is not one of the available choices." 4747 4785 msgstr "Faça uma escolha válida. %(value)s não está disponível." 4748 4786 4749 #: forms/fields.py:6 60 forms/fields.py:722 forms/models.py:9894787 #: forms/fields.py:671 forms/fields.py:733 forms/models.py:1002 4750 4788 msgid "Enter a list of values." 4751 4789 msgstr "Informe uma lista de valores." 4752 4790 4753 #: forms/formsets.py:29 3 forms/formsets.py:2954791 #: forms/formsets.py:298 forms/formsets.py:300 4754 4792 msgid "Order" 4755 4793 msgstr "Ordem" 4756 4794 4757 #: forms/models.py:5 504795 #: forms/models.py:562 4758 4796 #, python-format 4759 4797 msgid "Please correct the duplicate data for %(field)s." 4760 4798 msgstr "Por favor, corrija o valor duplicado para %(field)s." 4761 4799 4762 #: forms/models.py:5 544800 #: forms/models.py:566 4763 4801 #, python-format 4764 4802 msgid "Please correct the duplicate data for %(field)s, which must be unique." 4765 4803 msgstr "" 4766 4804 "Por favor, corrija o valor duplicado para %(field)s, o qual deve ser único" 4767 4805 4768 #: forms/models.py:5 604806 #: forms/models.py:572 4769 4807 #, python-format 4770 4808 msgid "" 4771 4809 "Please correct the duplicate data for %(field_name)s which must be unique " … … msgstr "" 4774 4812 "Por favor corrija os dados duplicados em %(field_name)s que deverá ser único " 4775 4813 "para o %(lookup)s em %(date_field)s." 4776 4814 4777 #: forms/models.py:5 684815 #: forms/models.py:580 4778 4816 msgid "Please correct the duplicate values below." 4779 4817 msgstr "Por favor, corrija os valores duplicados abaixo." 4780 4818 4781 #: forms/models.py:8 424819 #: forms/models.py:855 4782 4820 msgid "The inline foreign key did not match the parent instance primary key." 4783 4821 msgstr "" 4784 4822 "A chave estrangeira no inline não coincide com a chave primária na instância " 4785 4823 "pai." 4786 4824 4787 #: forms/models.py:9 084825 #: forms/models.py:921 4788 4826 msgid "Select a valid choice. That choice is not one of the available choices." 4789 4827 msgstr "Faça uma escolha válida. Sua escolha não é uma das disponíveis." 4790 4828 4791 #: forms/models.py: 9904829 #: forms/models.py:1003 4792 4830 #, python-format 4793 4831 msgid "Select a valid choice. %s is not one of the available choices." 4794 4832 msgstr "Faça uma escolha válida. %s não está disponível." 4795 4833 4796 #: forms/models.py: 9924834 #: forms/models.py:1005 4797 4835 #, python-format 4798 4836 msgid "\"%s\" is not a valid value for a primary key." 4799 4837 msgstr "\"%s\" não é um valor válido para uma chave primária." 4800 4838 4801 #: template/defaultfilters.py:7 814839 #: template/defaultfilters.py:776 4802 4840 msgid "yes,no,maybe" 4803 4841 msgstr "sim,não,talvez" 4804 4842 4805 #: template/defaultfilters.py:8 124843 #: template/defaultfilters.py:807 4806 4844 #, python-format 4807 4845 msgid "%(size)d byte" 4808 4846 msgid_plural "%(size)d bytes" 4809 4847 msgstr[0] "%(size)d byte" 4810 4848 msgstr[1] "%(size)d bytes" 4811 4849 4812 #: template/defaultfilters.py:8 144850 #: template/defaultfilters.py:809 4813 4851 #, python-format 4814 4852 msgid "%.1f KB" 4815 4853 msgstr "%.1f KB" 4816 4854 4817 #: template/defaultfilters.py:81 64855 #: template/defaultfilters.py:811 4818 4856 #, python-format 4819 4857 msgid "%.1f MB" 4820 4858 msgstr "%.1f MB" 4821 4859 4822 #: template/defaultfilters.py:81 74860 #: template/defaultfilters.py:812 4823 4861 #, python-format 4824 4862 msgid "%.1f GB" 4825 4863 msgstr "%.1f GB" … … msgstr "%(number)d %(type)s" 5082 5120 msgid ", %(number)d %(type)s" 5083 5121 msgstr ", %(number)d %(type)s" 5084 5122 5085 #: utils/translation/trans_real.py:51 25123 #: utils/translation/trans_real.py:519 5086 5124 msgid "DATE_FORMAT" 5087 5125 msgstr "j \\de N \\de Y" 5088 5126 5089 #: utils/translation/trans_real.py:5 135127 #: utils/translation/trans_real.py:520 5090 5128 msgid "DATETIME_FORMAT" 5091 5129 msgstr "j \\de N \\de Y à\\s H:i" 5092 5130 5093 #: utils/translation/trans_real.py:5 145131 #: utils/translation/trans_real.py:521 5094 5132 msgid "TIME_FORMAT" 5095 5133 msgstr "H:i" 5096 5134 5097 #: utils/translation/trans_real.py:5 355135 #: utils/translation/trans_real.py:542 5098 5136 msgid "YEAR_MONTH_FORMAT" 5099 5137 msgstr "F \\de Y" 5100 5138 5101 #: utils/translation/trans_real.py:5 365139 #: utils/translation/trans_real.py:543 5102 5140 msgid "MONTH_DAY_FORMAT" 5103 5141 msgstr "j \\de F" 5104 5142 … … msgstr "%(verbose_name)s: atualizado com sucesso." 5117 5155 msgid "The %(verbose_name)s was deleted." 5118 5156 msgstr "%(verbose_name)s: excluído." 5119 5157 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 3 import re, math 4 from random import randint 5 from django.db import models 6 from django import forms 7 from django.core.exceptions import ValidationError 8 from django.utils.translation import ugettext as _ 9 10 # ------------------------------------------------- 11 # Based in http://www.python.org.br/wiki/VerificadorDeCnpj 12 # 13 class 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 177 class 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 339 def 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 377 def 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 414 def 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 8 8 from django.forms.fields import Field, RegexField, CharField, Select 9 9 from django.utils.encoding import smart_unicode 10 10 from django.utils.translation import ugettext_lazy as _ 11 from django.contrib.localflavor.br.br_cpfcnpj import CPF,CNPJ 11 12 import re 12 13 13 14 phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$') … … class BRStateChoiceField(Field): 73 74 raise ValidationError(self.error_messages['invalid']) 74 75 return value 75 76 76 def DV_maker(v):77 if v >= 2:78 return 11 - v79 return 080 81 77 class BRCPFField(CharField): 82 78 """ 83 79 This field validate a CPF number or a CPF string. A CPF number is … … class BRCPFField(CharField): 93 89 } 94 90 95 91 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) 97 95 98 96 def clean(self, value): 99 97 """ … … class BRCPFField(CharField): 101 99 11-digit number. 102 100 """ 103 101 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 109 105 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 125 110 126 return orig_value111 return value 127 112 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 } 113 class 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) 134 123 135 124 def clean(self, value): 136 125 """ … … class BRCNPJField(Field): 138 127 group of 14 characters. 139 128 """ 140 129 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 146 133 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 162 138 163 return orig_value139 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
- + 1 from django.db import models 2 from django.contrib.localflavor.br.br_cpfcnpj import CPF,CNPJ 3 from django.contrib.localflavor.br import forms 4 5 EMPTY_VALUES=(None,'') 6 7 class 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 44 class 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.'] 64 64 >>> f.clean('12345-123') 65 65 u'12345-123' 66 66 67 # BRCNPJField ############################################################68 69 >>> from django.contrib.localflavor.br.forms import BRCNPJField70 >>> 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 BRCPFField104 >>> 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 155 67 # BRPhoneNumberField ######################################################### 156 68 157 69 >>> 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 ModelForm2 from models import Place3 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 models2 from django.contrib.localflavor.us.models import USStateField3 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 TestCase2 from models import Place3 from forms import PlaceForm4 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
- + 1 from django import forms 2 from models import BRCPFCNPJ 3 4 class 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
- + 1 from django.db import models 2 from django.contrib.localflavor.br.models import BRCPFField, BRCNPJField 3 4 class 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 15 class 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
- + 1 from django.test import TestCase 2 from django import forms 3 from django.contrib.localflavor.br.br_cpfcnpj import CPF, CNPJ, CPFGenerator,\ 4 CNPJGenerator 5 from django.contrib.localflavor.br import forms as brforms 6 from models import BRCPFCNPJ, BRCPFCNPJ2 7 from forms import BRCPFCNPJForm 8 9 from random import choice 10 11 class 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
- + 1 import unittest 2 from django.test import TestCase 3 4 # just import your tests here 5 from us.tests import * 6 from 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. 11 testlist=[] 12 for 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 19 def 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
- + 1 from django.forms import ModelForm 2 from models import USPlace 3 4 class 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
- + 1 from django.db import models 2 from 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 7 class 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
- + 1 from django.test import TestCase 2 from forms import USPlaceForm 3 4 class 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)