Fixed #15013 -- Added Russian (ru) localflavor package. Thanks, blackraven and Julien Phalip.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16076 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2011-04-22 12:03:30 +00:00
parent 0e5d5d6218
commit e1f7bc0a41
7 changed files with 356 additions and 0 deletions

View File

@ -0,0 +1,68 @@
"""
Russian-specific forms helpers
"""
import re
from django.core.validators import EMPTY_VALUES
from django.forms import ValidationError
from django.forms.fields import CharField, Select, RegexField
from django.utils.translation import ugettext_lazy as _
phone_digits_re = re.compile(r'^(?:[78]-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$')
class RUCountySelect(Select):
"""
A Select widget that uses a list of Russian Counties as its choices.
"""
def __init__(self, attrs=None):
from ru_regions import RU_COUNTY_CHOICES
super(RUCountySelect, self).__init__(attrs, choices=RU_COUNTY_CHOICES)
class RURegionSelect(Select):
"""
A Select widget that uses a list of Russian Regions as its choices.
"""
def __init__(self, attrs=None):
from ru_regions import RU_REGIONS_CHOICES
super(RURegionSelect, self).__init__(attrs, choices=RU_REGIONS_CHOICES)
class RUPostalCodeField(RegexField):
"""
Russian Postal code field.
Format: XXXXXX, where X is any digit, and first digit is not zero.
"""
default_error_messages = {
'invalid': _(u'Enter a postal code in the format XXXXXX.'),
}
def __init__(self, *args, **kwargs):
super(RUPostalCodeField, self).__init__(r'^\d{6}$',
max_length=None, min_length=None, *args, **kwargs)
class RUPassportNumberField(RegexField):
"""
Russian internal passport number format:
XXXX XXXXXX where X - any digit.
"""
default_error_messages = {
'invalid': _(u'Enter a passport number in the format XXXX XXXXXX.'),
}
def __init__(self, *args, **kwargs):
super(RUPassportNumberField, self).__init__(r'^\d{4} \d{6}$',
max_length=None, min_length=None, *args, **kwargs)
class RUAlienPassportNumberField(RegexField):
"""
Russian alien's passport number format:
XX XXXXXXX where X - any digit.
"""
default_error_messages = {
'invalid': _(u'Enter a passport number in the format XX XXXXXXX.'),
}
def __init__(self, *args, **kwargs):
super(RUAlienPassportNumberField, self).__init__(r'^\d{2} \d{7}$',
max_length=None, min_length=None, *args, **kwargs)

View File

@ -0,0 +1,104 @@
# -*- encoding: utf-8 -*-
"""
Sources:
http://ru.wikipedia.org/wiki/Коды_субъектов_Российской_Федерации
http://ru.wikipedia.org/wiki/Федеральные_округа_Российской_Федерации
"""
from django.utils.translation import ugettext_lazy as _
RU_COUNTY_CHOICES = (
("Central Federal County", _("Central Federal County")),
("South Federal County", _("South Federal County")),
("North-West Federal County", _("North-West Federal County")),
("Far-East Federal County", _("Far-East Federal County")),
("Siberian Federal County", _("Siberian Federal County")),
("Ural Federal County", _("Ural Federal County")),
("Privolzhsky Federal County", _("Privolzhsky Federal County")),
("North-Caucasian Federal County", _("North-Caucasian Federal County"))
)
RU_REGIONS_CHOICES = (
("77", _("Moskva")),
("78", _("Saint-Peterburg")),
("50", _("Moskovskaya oblast'")),
("01", _("Adygeya, Respublika")),
("02", _("Bashkortostan, Respublika")),
("03", _("Buryatia, Respublika")),
("04", _("Altay, Respublika")),
("05", _("Dagestan, Respublika")),
("06", _("Ingushskaya Respublika")),
("07", _("Kabardino-Balkarskaya Respublika")),
("08", _("Kalmykia, Respublika")),
("09", _("Karachaevo-Cherkesskaya Respublika")),
("10", _("Karelia, Respublika")),
("11", _("Komi, Respublika")),
("12", _("Mariy Ehl, Respublika")),
("13", _("Mordovia, Respublika")),
("14", _("Sakha, Respublika (Yakutiya)")),
("15", _("Severnaya Osetia, Respublika (Alania)")),
("16", _("Tatarstan, Respublika")),
("17", _("Tyva, Respublika (Tuva)")),
("18", _("Udmurtskaya Respublika")),
("19", _("Khakassiya, Respublika")),
("95", _("Chechenskaya Respublika")),
("21", _("Chuvashskaya Respublika")),
("22", _("Altayskiy Kray")),
("80", _("Zabaykalskiy Kray")),
("82", _("Kamchatskiy Kray")),
("23", _("Krasnodarskiy Kray")),
("24", _("Krasnoyarskiy Kray")),
("81", _("Permskiy Kray")),
("25", _("Primorskiy Kray")),
("26", _("Stavropol'siyy Kray")),
("27", _("Khabarovskiy Kray")),
("28", _("Amurskaya oblast'")),
("29", _("Arkhangel'skaya oblast'")),
("30", _("Astrakhanskaya oblast'")),
("31", _("Belgorodskaya oblast'")),
("32", _("Bryanskaya oblast'")),
("33", _("Vladimirskaya oblast'")),
("34", _("Volgogradskaya oblast'")),
("35", _("Vologodskaya oblast'")),
("36", _("Voronezhskaya oblast'")),
("37", _("Ivanovskaya oblast'")),
("38", _("Irkutskaya oblast'")),
("39", _("Kaliningradskaya oblast'")),
("40", _("Kaluzhskaya oblast'")),
("42", _("Kemerovskaya oblast'")),
("43", _("Kirovskaya oblast'")),
("44", _("Kostromskaya oblast'")),
("45", _("Kurganskaya oblast'")),
("46", _("Kurskaya oblast'")),
("47", _("Leningradskaya oblast'")),
("48", _("Lipeckaya oblast'")),
("49", _("Magadanskaya oblast'")),
("51", _("Murmanskaya oblast'")),
("52", _("Nizhegorodskaja oblast'")),
("53", _("Novgorodskaya oblast'")),
("54", _("Novosibirskaya oblast'")),
("55", _("Omskaya oblast'")),
("56", _("Orenburgskaya oblast'")),
("57", _("Orlovskaya oblast'")),
("58", _("Penzenskaya oblast'")),
("60", _("Pskovskaya oblast'")),
("61", _("Rostovskaya oblast'")),
("62", _("Rjazanskaya oblast'")),
("63", _("Samarskaya oblast'")),
("64", _("Saratovskaya oblast'")),
("65", _("Sakhalinskaya oblast'")),
("66", _("Sverdlovskaya oblast'")),
("67", _("Smolenskaya oblast'")),
("68", _("Tambovskaya oblast'")),
("69", _("Tverskaya oblast'")),
("70", _("Tomskaya oblast'")),
("71", _("Tul'skaya oblast'")),
("72", _("Tyumenskaya oblast'")),
("73", _("Ul'ianovskaya oblast'")),
("74", _("Chelyabinskaya oblast'")),
("76", _("Yaroslavskaya oblast'")),
("79", _("Evreyskaya avtonomnaja oblast'")),
("83", _("Neneckiy autonomnyy okrug")),
("86", _("Khanty-Mansiyskiy avtonomnyy okrug - Yugra")),
("87", _("Chukotskiy avtonomnyy okrug")),
("89", _("Yamalo-Neneckiy avtonomnyy okrug"))
)

View File

@ -63,6 +63,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are:
* Poland_ * Poland_
* Portugal_ * Portugal_
* Romania_ * Romania_
* Russia_
* Slovakia_ * Slovakia_
* `South Africa`_ * `South Africa`_
* Spain_ * Spain_
@ -113,6 +114,7 @@ Here's an example of how to use them::
.. _Poland: `Poland (pl)`_ .. _Poland: `Poland (pl)`_
.. _Portugal: `Portugal (pt)`_ .. _Portugal: `Portugal (pt)`_
.. _Romania: `Romania (ro)`_ .. _Romania: `Romania (ro)`_
.. _Russia: `Russia (ru)`_
.. _Slovakia: `Slovakia (sk)`_ .. _Slovakia: `Slovakia (sk)`_
.. _South Africa: `South Africa (za)`_ .. _South Africa: `South Africa (za)`_
.. _Spain: `Spain (es)`_ .. _Spain: `Spain (es)`_
@ -190,6 +192,8 @@ Argentina (``ar``)
Australia (``au``) Australia (``au``)
============================================= =============================================
.. versionadded:: 1.4
.. class:: au.forms.AUPostCodeField .. class:: au.forms.AUPostCodeField
A form field that validates input as an Australian postcode. A form field that validates input as an Australian postcode.
@ -342,6 +346,8 @@ Chile (``cl``)
China (``cn``) China (``cn``)
============== ==============
.. versionadded:: 1.4
.. class:: cn.forms.CNProvinceSelect .. class:: cn.forms.CNProvinceSelect
A ``Select`` widget that uses a list of Chinese regions as its choices. A ``Select`` widget that uses a list of Chinese regions as its choices.
@ -756,6 +762,34 @@ Romania (``ro``)
A form field that validates Romanian postal codes. A form field that validates Romanian postal codes.
Russia (``ru``)
===============
.. versionadded:: 1.4
.. class:: ru.forms.RUPostalCodeField
Russian Postal code field. The valid format is XXXXXX, where X is any
digit and the first digit is not zero.
.. class:: ru.forms.RUCountySelect
A ``Select`` widget that uses a list of Russian Counties as its choices.
.. class:: ru.forms.RURegionSelect
A ``Select`` widget that uses a list of Russian Regions as its choices.
.. class:: ru.forms.RUPassportNumberField
Russian internal passport number. The valid format is XXXX XXXXXX, where X
is any digit.
.. class:: ru.forms.RUAlienPassportNumberField
Russian alien's passport number. The valid format is XX XXXXXXX, where X
is any digit.
Slovakia (``sk``) Slovakia (``sk``)
================= =================

View File

@ -0,0 +1,148 @@
from django.contrib.localflavor.ru.forms import *
from utils import LocalFlavorTestCase
class RULocalFlavorTests(LocalFlavorTestCase):
def test_RUPassportNumberField(self):
error = [u'Enter a passport number in the format XXXX XXXXXX.']
valid = {
'1981 211204': '1981 211204',
'0305 967876': '0305 967876',
}
invalid = {
'1981 2112044': error,
'1981 23220': error,
'9981211201': error,
}
self.assertFieldOutput(RUPassportNumberField, valid, invalid)
def test_RUAlienPassportNumberField(self):
error = [u'Enter a passport number in the format XX XXXXXXX.']
valid = {
'19 8111204': '19 8111204',
'03 0567876': '03 0567876',
}
invalid = {
'198 1112044': error,
'19 81123220': error,
'99 812112': error,
}
self.assertFieldOutput(RUAlienPassportNumberField, valid, invalid)
def test_RUPostalCodeField(self):
error = [u'Enter a postal code in the format XXXXXX.']
valid = {
'987654': '987654',
'123456': '123456'
}
invalid = {
'123 34': error,
'1234567': error,
'12345': error
}
self.assertFieldOutput(RUPostalCodeField, valid, invalid)
def test_RUCountySelect(self):
f = RUCountySelect()
out = u'''<select name="county">
<option value="Central Federal County">Central Federal County</option>
<option value="South Federal County">South Federal County</option>
<option value="North-West Federal County">North-West Federal County</option>
<option value="Far-East Federal County">Far-East Federal County</option>
<option value="Siberian Federal County">Siberian Federal County</option>
<option value="Ural Federal County">Ural Federal County</option>
<option value="Privolzhsky Federal County">Privolzhsky Federal County</option>
<option value="North-Caucasian Federal County">North-Caucasian Federal County</option>
</select>'''
self.assertEqual(f.render('county', None), out)
def test_RURegionSelect(self):
f = RURegionSelect()
out = u'''<select name="region">
<option value="77">Moskva</option>
<option value="78">Saint-Peterburg</option>
<option value="50">Moskovskaya oblast&#39;</option>
<option value="01">Adygeya, Respublika</option>
<option value="02">Bashkortostan, Respublika</option>
<option value="03">Buryatia, Respublika</option>
<option value="04">Altay, Respublika</option>
<option value="05">Dagestan, Respublika</option>
<option value="06">Ingushskaya Respublika</option>
<option value="07">Kabardino-Balkarskaya Respublika</option>
<option value="08">Kalmykia, Respublika</option>
<option value="09">Karachaevo-Cherkesskaya Respublika</option>
<option value="10">Karelia, Respublika</option>
<option value="11">Komi, Respublika</option>
<option value="12">Mariy Ehl, Respublika</option>
<option value="13">Mordovia, Respublika</option>
<option value="14">Sakha, Respublika (Yakutiya)</option>
<option value="15">Severnaya Osetia, Respublika (Alania)</option>
<option value="16">Tatarstan, Respublika</option>
<option value="17">Tyva, Respublika (Tuva)</option>
<option value="18">Udmurtskaya Respublika</option>
<option value="19">Khakassiya, Respublika</option>
<option value="95">Chechenskaya Respublika</option>
<option value="21">Chuvashskaya Respublika</option>
<option value="22">Altayskiy Kray</option>
<option value="80">Zabaykalskiy Kray</option>
<option value="82">Kamchatskiy Kray</option>
<option value="23">Krasnodarskiy Kray</option>
<option value="24">Krasnoyarskiy Kray</option>
<option value="81">Permskiy Kray</option>
<option value="25">Primorskiy Kray</option>
<option value="26">Stavropol&#39;siyy Kray</option>
<option value="27">Khabarovskiy Kray</option>
<option value="28">Amurskaya oblast&#39;</option>
<option value="29">Arkhangel&#39;skaya oblast&#39;</option>
<option value="30">Astrakhanskaya oblast&#39;</option>
<option value="31">Belgorodskaya oblast&#39;</option>
<option value="32">Bryanskaya oblast&#39;</option>
<option value="33">Vladimirskaya oblast&#39;</option>
<option value="34">Volgogradskaya oblast&#39;</option>
<option value="35">Vologodskaya oblast&#39;</option>
<option value="36">Voronezhskaya oblast&#39;</option>
<option value="37">Ivanovskaya oblast&#39;</option>
<option value="38">Irkutskaya oblast&#39;</option>
<option value="39">Kaliningradskaya oblast&#39;</option>
<option value="40">Kaluzhskaya oblast&#39;</option>
<option value="42">Kemerovskaya oblast&#39;</option>
<option value="43">Kirovskaya oblast&#39;</option>
<option value="44">Kostromskaya oblast&#39;</option>
<option value="45">Kurganskaya oblast&#39;</option>
<option value="46">Kurskaya oblast&#39;</option>
<option value="47">Leningradskaya oblast&#39;</option>
<option value="48">Lipeckaya oblast&#39;</option>
<option value="49">Magadanskaya oblast&#39;</option>
<option value="51">Murmanskaya oblast&#39;</option>
<option value="52">Nizhegorodskaja oblast&#39;</option>
<option value="53">Novgorodskaya oblast&#39;</option>
<option value="54">Novosibirskaya oblast&#39;</option>
<option value="55">Omskaya oblast&#39;</option>
<option value="56">Orenburgskaya oblast&#39;</option>
<option value="57">Orlovskaya oblast&#39;</option>
<option value="58">Penzenskaya oblast&#39;</option>
<option value="60">Pskovskaya oblast&#39;</option>
<option value="61">Rostovskaya oblast&#39;</option>
<option value="62">Rjazanskaya oblast&#39;</option>
<option value="63">Samarskaya oblast&#39;</option>
<option value="64">Saratovskaya oblast&#39;</option>
<option value="65">Sakhalinskaya oblast&#39;</option>
<option value="66">Sverdlovskaya oblast&#39;</option>
<option value="67" selected="selected">Smolenskaya oblast&#39;</option>
<option value="68">Tambovskaya oblast&#39;</option>
<option value="69">Tverskaya oblast&#39;</option>
<option value="70">Tomskaya oblast&#39;</option>
<option value="71">Tul&#39;skaya oblast&#39;</option>
<option value="72">Tyumenskaya oblast&#39;</option>
<option value="73">Ul&#39;ianovskaya oblast&#39;</option>
<option value="74">Chelyabinskaya oblast&#39;</option>
<option value="76">Yaroslavskaya oblast&#39;</option>
<option value="79">Evreyskaya avtonomnaja oblast&#39;</option>
<option value="83">Neneckiy autonomnyy okrug</option>
<option value="86">Khanty-Mansiyskiy avtonomnyy okrug - Yugra</option>
<option value="87">Chukotskiy avtonomnyy okrug</option>
<option value="89">Yamalo-Neneckiy avtonomnyy okrug</option>
</select>'''
self.assertEqual(f.render('region', '67'), out)

View File

@ -24,6 +24,7 @@ from localflavor.nl import NLLocalFlavorTests
from localflavor.pl import PLLocalFlavorTests from localflavor.pl import PLLocalFlavorTests
from localflavor.pt import PTLocalFlavorTests from localflavor.pt import PTLocalFlavorTests
from localflavor.ro import ROLocalFlavorTests from localflavor.ro import ROLocalFlavorTests
from localflavor.ru import RULocalFlavorTests
from localflavor.se import SELocalFlavorTests from localflavor.se import SELocalFlavorTests
from localflavor.sk import SKLocalFlavorTests from localflavor.sk import SKLocalFlavorTests
from localflavor.tr import TRLocalFlavorTests from localflavor.tr import TRLocalFlavorTests

View File

@ -38,6 +38,7 @@ from regressiontests.forms.localflavortests import (
PLLocalFlavorTests, PLLocalFlavorTests,
PTLocalFlavorTests, PTLocalFlavorTests,
ROLocalFlavorTests, ROLocalFlavorTests,
RULocalFlavorTests,
SELocalFlavorTests, SELocalFlavorTests,
SKLocalFlavorTests, SKLocalFlavorTests,
TRLocalFlavorTests, TRLocalFlavorTests,