Author: jezdez Date: 2011-04-22 05:03:30 -0700 (Fri, 22 Apr 2011) New Revision: 16076
Added: django/trunk/django/contrib/localflavor/ru/ django/trunk/django/contrib/localflavor/ru/__init__.py django/trunk/django/contrib/localflavor/ru/forms.py django/trunk/django/contrib/localflavor/ru/ru_regions.py django/trunk/tests/regressiontests/forms/localflavor/ru.py Modified: django/trunk/docs/ref/contrib/localflavor.txt django/trunk/tests/regressiontests/forms/localflavortests.py django/trunk/tests/regressiontests/forms/tests/__init__.py Log: Fixed #15013 -- Added Russian (ru) localflavor package. Thanks, blackraven and Julien Phalip. Added: django/trunk/django/contrib/localflavor/ru/__init__.py =================================================================== Added: django/trunk/django/contrib/localflavor/ru/forms.py =================================================================== --- django/trunk/django/contrib/localflavor/ru/forms.py (rev 0) +++ django/trunk/django/contrib/localflavor/ru/forms.py 2011-04-22 12:03:30 UTC (rev 16076) @@ -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) Added: django/trunk/django/contrib/localflavor/ru/ru_regions.py =================================================================== --- django/trunk/django/contrib/localflavor/ru/ru_regions.py (rev 0) +++ django/trunk/django/contrib/localflavor/ru/ru_regions.py 2011-04-22 12:03:30 UTC (rev 16076) @@ -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")) +) Modified: django/trunk/docs/ref/contrib/localflavor.txt =================================================================== --- django/trunk/docs/ref/contrib/localflavor.txt 2011-04-22 12:03:18 UTC (rev 16075) +++ django/trunk/docs/ref/contrib/localflavor.txt 2011-04-22 12:03:30 UTC (rev 16076) @@ -63,6 +63,7 @@ * Poland_ * Portugal_ * Romania_ + * Russia_ * Slovakia_ * `South Africa`_ * Spain_ @@ -113,6 +114,7 @@ .. _Poland: `Poland (pl)`_ .. _Portugal: `Portugal (pt)`_ .. _Romania: `Romania (ro)`_ +.. _Russia: `Russia (ru)`_ .. _Slovakia: `Slovakia (sk)`_ .. _South Africa: `South Africa (za)`_ .. _Spain: `Spain (es)`_ @@ -190,6 +192,8 @@ Australia (``au``) ============================================= +.. versionadded:: 1.4 + .. class:: au.forms.AUPostCodeField A form field that validates input as an Australian postcode. @@ -342,6 +346,8 @@ China (``cn``) ============== +.. versionadded:: 1.4 + .. class:: cn.forms.CNProvinceSelect A ``Select`` widget that uses a list of Chinese regions as its choices. @@ -756,6 +762,34 @@ 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``) ================= Added: django/trunk/tests/regressiontests/forms/localflavor/ru.py =================================================================== --- django/trunk/tests/regressiontests/forms/localflavor/ru.py (rev 0) +++ django/trunk/tests/regressiontests/forms/localflavor/ru.py 2011-04-22 12:03:30 UTC (rev 16076) @@ -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'</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'siyy Kray</option> +<option value="27">Khabarovskiy Kray</option> +<option value="28">Amurskaya oblast'</option> +<option value="29">Arkhangel'skaya oblast'</option> +<option value="30">Astrakhanskaya oblast'</option> +<option value="31">Belgorodskaya oblast'</option> +<option value="32">Bryanskaya oblast'</option> +<option value="33">Vladimirskaya oblast'</option> +<option value="34">Volgogradskaya oblast'</option> +<option value="35">Vologodskaya oblast'</option> +<option value="36">Voronezhskaya oblast'</option> +<option value="37">Ivanovskaya oblast'</option> +<option value="38">Irkutskaya oblast'</option> +<option value="39">Kaliningradskaya oblast'</option> +<option value="40">Kaluzhskaya oblast'</option> +<option value="42">Kemerovskaya oblast'</option> +<option value="43">Kirovskaya oblast'</option> +<option value="44">Kostromskaya oblast'</option> +<option value="45">Kurganskaya oblast'</option> +<option value="46">Kurskaya oblast'</option> +<option value="47">Leningradskaya oblast'</option> +<option value="48">Lipeckaya oblast'</option> +<option value="49">Magadanskaya oblast'</option> +<option value="51">Murmanskaya oblast'</option> +<option value="52">Nizhegorodskaja oblast'</option> +<option value="53">Novgorodskaya oblast'</option> +<option value="54">Novosibirskaya oblast'</option> +<option value="55">Omskaya oblast'</option> +<option value="56">Orenburgskaya oblast'</option> +<option value="57">Orlovskaya oblast'</option> +<option value="58">Penzenskaya oblast'</option> +<option value="60">Pskovskaya oblast'</option> +<option value="61">Rostovskaya oblast'</option> +<option value="62">Rjazanskaya oblast'</option> +<option value="63">Samarskaya oblast'</option> +<option value="64">Saratovskaya oblast'</option> +<option value="65">Sakhalinskaya oblast'</option> +<option value="66">Sverdlovskaya oblast'</option> +<option value="67" selected="selected">Smolenskaya oblast'</option> +<option value="68">Tambovskaya oblast'</option> +<option value="69">Tverskaya oblast'</option> +<option value="70">Tomskaya oblast'</option> +<option value="71">Tul'skaya oblast'</option> +<option value="72">Tyumenskaya oblast'</option> +<option value="73">Ul'ianovskaya oblast'</option> +<option value="74">Chelyabinskaya oblast'</option> +<option value="76">Yaroslavskaya oblast'</option> +<option value="79">Evreyskaya avtonomnaja oblast'</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) Modified: django/trunk/tests/regressiontests/forms/localflavortests.py =================================================================== --- django/trunk/tests/regressiontests/forms/localflavortests.py 2011-04-22 12:03:18 UTC (rev 16075) +++ django/trunk/tests/regressiontests/forms/localflavortests.py 2011-04-22 12:03:30 UTC (rev 16076) @@ -24,6 +24,7 @@ from localflavor.pl import PLLocalFlavorTests from localflavor.pt import PTLocalFlavorTests from localflavor.ro import ROLocalFlavorTests +from localflavor.ru import RULocalFlavorTests from localflavor.se import SELocalFlavorTests from localflavor.sk import SKLocalFlavorTests from localflavor.tr import TRLocalFlavorTests Modified: django/trunk/tests/regressiontests/forms/tests/__init__.py =================================================================== --- django/trunk/tests/regressiontests/forms/tests/__init__.py 2011-04-22 12:03:18 UTC (rev 16075) +++ django/trunk/tests/regressiontests/forms/tests/__init__.py 2011-04-22 12:03:30 UTC (rev 16076) @@ -38,6 +38,7 @@ PLLocalFlavorTests, PTLocalFlavorTests, ROLocalFlavorTests, + RULocalFlavorTests, SELocalFlavorTests, SKLocalFlavorTests, TRLocalFlavorTests, -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-updates@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.