Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #15013 -- Added Russian (ru) localflavor package. Thanks, black…

…raven and Julien Phalip.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16076 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e1f7bc0a410a4ce4eb3ab1e1426847f622e50539 1 parent 0e5d5d6
Jannis Leidel authored April 22, 2011
68  django/contrib/localflavor/ru/forms.py
... ...
@@ -0,0 +1,68 @@
  1
+"""
  2
+Russian-specific forms helpers
  3
+"""
  4
+import re
  5
+
  6
+from django.core.validators import EMPTY_VALUES
  7
+from django.forms import ValidationError
  8
+from django.forms.fields import CharField, Select, RegexField
  9
+from django.utils.translation import ugettext_lazy as _
  10
+
  11
+phone_digits_re = re.compile(r'^(?:[78]-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$')
  12
+
  13
+
  14
+class RUCountySelect(Select):
  15
+    """
  16
+    A Select widget that uses a list of Russian Counties as its choices.
  17
+    """
  18
+    def __init__(self, attrs=None):
  19
+        from ru_regions import RU_COUNTY_CHOICES
  20
+        super(RUCountySelect, self).__init__(attrs, choices=RU_COUNTY_CHOICES)
  21
+
  22
+
  23
+class RURegionSelect(Select):
  24
+    """
  25
+    A Select widget that uses a list of Russian Regions as its choices.
  26
+    """
  27
+    def __init__(self, attrs=None):
  28
+        from ru_regions import RU_REGIONS_CHOICES
  29
+        super(RURegionSelect, self).__init__(attrs, choices=RU_REGIONS_CHOICES)
  30
+
  31
+
  32
+class RUPostalCodeField(RegexField):
  33
+    """
  34
+    Russian Postal code field.
  35
+    Format: XXXXXX, where X is any digit, and first digit is not zero.
  36
+    """
  37
+    default_error_messages = {
  38
+        'invalid': _(u'Enter a postal code in the format XXXXXX.'),
  39
+    }
  40
+    def __init__(self, *args, **kwargs):
  41
+        super(RUPostalCodeField, self).__init__(r'^\d{6}$',
  42
+            max_length=None, min_length=None, *args, **kwargs)
  43
+
  44
+
  45
+class RUPassportNumberField(RegexField):
  46
+    """
  47
+    Russian internal passport number format:
  48
+    XXXX XXXXXX where X - any digit.
  49
+    """
  50
+    default_error_messages = {
  51
+        'invalid': _(u'Enter a passport number in the format XXXX XXXXXX.'),
  52
+    }
  53
+    def __init__(self, *args, **kwargs):
  54
+        super(RUPassportNumberField, self).__init__(r'^\d{4} \d{6}$',
  55
+            max_length=None, min_length=None, *args, **kwargs)
  56
+
  57
+
  58
+class RUAlienPassportNumberField(RegexField):
  59
+    """
  60
+    Russian alien's passport number format:
  61
+    XX XXXXXXX where X - any digit.
  62
+    """
  63
+    default_error_messages = {
  64
+        'invalid': _(u'Enter a passport number in the format XX XXXXXXX.'),
  65
+    }
  66
+    def __init__(self, *args, **kwargs):
  67
+        super(RUAlienPassportNumberField, self).__init__(r'^\d{2} \d{7}$',
  68
+            max_length=None, min_length=None, *args, **kwargs)
104  django/contrib/localflavor/ru/ru_regions.py
... ...
@@ -0,0 +1,104 @@
  1
+# -*- encoding: utf-8 -*-
  2
+"""
  3
+Sources:
  4
+    http://ru.wikipedia.org/wiki/Коды_субъектов_Российской_Федерации
  5
+    http://ru.wikipedia.org/wiki/Федеральные_округа_Российской_Федерации
  6
+"""
  7
+from django.utils.translation import ugettext_lazy as _
  8
+
  9
+RU_COUNTY_CHOICES = (
  10
+    ("Central Federal County", _("Central Federal County")),
  11
+    ("South Federal County", _("South Federal County")),
  12
+    ("North-West Federal County", _("North-West Federal County")),
  13
+    ("Far-East Federal County", _("Far-East Federal County")),
  14
+    ("Siberian Federal County", _("Siberian Federal County")),
  15
+    ("Ural Federal County", _("Ural Federal County")),
  16
+    ("Privolzhsky Federal County", _("Privolzhsky Federal County")),
  17
+    ("North-Caucasian Federal County", _("North-Caucasian Federal County"))
  18
+)
  19
+
  20
+RU_REGIONS_CHOICES = (
  21
+    ("77", _("Moskva")),
  22
+    ("78", _("Saint-Peterburg")),
  23
+    ("50", _("Moskovskaya oblast'")),
  24
+    ("01", _("Adygeya, Respublika")),
  25
+    ("02", _("Bashkortostan, Respublika")),
  26
+    ("03", _("Buryatia, Respublika")),
  27
+    ("04", _("Altay, Respublika")),
  28
+    ("05", _("Dagestan, Respublika")),
  29
+    ("06", _("Ingushskaya Respublika")),
  30
+    ("07", _("Kabardino-Balkarskaya Respublika")),
  31
+    ("08", _("Kalmykia, Respublika")),
  32
+    ("09", _("Karachaevo-Cherkesskaya Respublika")),
  33
+    ("10", _("Karelia, Respublika")),
  34
+    ("11", _("Komi, Respublika")),
  35
+    ("12", _("Mariy Ehl, Respublika")),
  36
+    ("13", _("Mordovia, Respublika")),
  37
+    ("14", _("Sakha, Respublika (Yakutiya)")),
  38
+    ("15", _("Severnaya Osetia, Respublika (Alania)")),
  39
+    ("16", _("Tatarstan, Respublika")),
  40
+    ("17", _("Tyva, Respublika (Tuva)")),
  41
+    ("18", _("Udmurtskaya Respublika")),
  42
+    ("19", _("Khakassiya, Respublika")),
  43
+    ("95", _("Chechenskaya Respublika")),
  44
+    ("21", _("Chuvashskaya Respublika")),
  45
+    ("22", _("Altayskiy Kray")),
  46
+    ("80", _("Zabaykalskiy Kray")),
  47
+    ("82", _("Kamchatskiy Kray")),
  48
+    ("23", _("Krasnodarskiy Kray")),
  49
+    ("24", _("Krasnoyarskiy Kray")),
  50
+    ("81", _("Permskiy Kray")),
  51
+    ("25", _("Primorskiy Kray")),
  52
+    ("26", _("Stavropol'siyy Kray")),
  53
+    ("27", _("Khabarovskiy Kray")),
  54
+    ("28", _("Amurskaya oblast'")),
  55
+    ("29", _("Arkhangel'skaya oblast'")),
  56
+    ("30", _("Astrakhanskaya oblast'")),
  57
+    ("31", _("Belgorodskaya oblast'")),
  58
+    ("32", _("Bryanskaya oblast'")),
  59
+    ("33", _("Vladimirskaya oblast'")),
  60
+    ("34", _("Volgogradskaya oblast'")),
  61
+    ("35", _("Vologodskaya oblast'")),
  62
+    ("36", _("Voronezhskaya oblast'")),
  63
+    ("37", _("Ivanovskaya oblast'")),
  64
+    ("38", _("Irkutskaya oblast'")),
  65
+    ("39", _("Kaliningradskaya oblast'")),
  66
+    ("40", _("Kaluzhskaya oblast'")),
  67
+    ("42", _("Kemerovskaya oblast'")),
  68
+    ("43", _("Kirovskaya oblast'")),
  69
+    ("44", _("Kostromskaya oblast'")),
  70
+    ("45", _("Kurganskaya oblast'")),
  71
+    ("46", _("Kurskaya oblast'")),
  72
+    ("47", _("Leningradskaya oblast'")),
  73
+    ("48", _("Lipeckaya oblast'")),
  74
+    ("49", _("Magadanskaya oblast'")),
  75
+    ("51", _("Murmanskaya oblast'")),
  76
+    ("52", _("Nizhegorodskaja oblast'")),
  77
+    ("53", _("Novgorodskaya oblast'")),
  78
+    ("54", _("Novosibirskaya oblast'")),
  79
+    ("55", _("Omskaya oblast'")),
  80
+    ("56", _("Orenburgskaya oblast'")),
  81
+    ("57", _("Orlovskaya oblast'")),
  82
+    ("58", _("Penzenskaya oblast'")),
  83
+    ("60", _("Pskovskaya oblast'")),
  84
+    ("61", _("Rostovskaya oblast'")),
  85
+    ("62", _("Rjazanskaya oblast'")),
  86
+    ("63", _("Samarskaya oblast'")),
  87
+    ("64", _("Saratovskaya oblast'")),
  88
+    ("65", _("Sakhalinskaya oblast'")),
  89
+    ("66", _("Sverdlovskaya oblast'")),
  90
+    ("67", _("Smolenskaya oblast'")),
  91
+    ("68", _("Tambovskaya oblast'")),
  92
+    ("69", _("Tverskaya oblast'")),
  93
+    ("70", _("Tomskaya oblast'")),
  94
+    ("71", _("Tul'skaya oblast'")),
  95
+    ("72", _("Tyumenskaya oblast'")),
  96
+    ("73", _("Ul'ianovskaya oblast'")),
  97
+    ("74", _("Chelyabinskaya oblast'")),
  98
+    ("76", _("Yaroslavskaya oblast'")),
  99
+    ("79", _("Evreyskaya avtonomnaja oblast'")),
  100
+    ("83", _("Neneckiy autonomnyy okrug")),
  101
+    ("86", _("Khanty-Mansiyskiy avtonomnyy okrug - Yugra")),
  102
+    ("87", _("Chukotskiy avtonomnyy okrug")),
  103
+    ("89", _("Yamalo-Neneckiy avtonomnyy okrug"))
  104
+)
34  docs/ref/contrib/localflavor.txt
@@ -63,6 +63,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are:
63 63
     * Poland_
64 64
     * Portugal_
65 65
     * Romania_
  66
+    * Russia_
66 67
     * Slovakia_
67 68
     * `South Africa`_
68 69
     * Spain_
@@ -113,6 +114,7 @@ Here's an example of how to use them::
113 114
 .. _Poland: `Poland (pl)`_
114 115
 .. _Portugal: `Portugal (pt)`_
115 116
 .. _Romania: `Romania (ro)`_
  117
+.. _Russia: `Russia (ru)`_
116 118
 .. _Slovakia: `Slovakia (sk)`_
117 119
 .. _South Africa: `South Africa (za)`_
118 120
 .. _Spain: `Spain (es)`_
@@ -190,6 +192,8 @@ Argentina (``ar``)
190 192
 Australia (``au``)
191 193
 =============================================
192 194
 
  195
+.. versionadded:: 1.4
  196
+
193 197
 .. class:: au.forms.AUPostCodeField
194 198
 
195 199
     A form field that validates input as an Australian postcode.
@@ -342,6 +346,8 @@ Chile (``cl``)
342 346
 China (``cn``)
343 347
 ==============
344 348
 
  349
+.. versionadded:: 1.4
  350
+
345 351
 .. class:: cn.forms.CNProvinceSelect
346 352
 
347 353
     A ``Select`` widget that uses a list of Chinese regions as its choices.
@@ -756,6 +762,34 @@ Romania (``ro``)
756 762
 
757 763
     A form field that validates Romanian postal codes.
758 764
 
  765
+Russia (``ru``)
  766
+===============
  767
+
  768
+.. versionadded:: 1.4
  769
+
  770
+.. class:: ru.forms.RUPostalCodeField
  771
+
  772
+    Russian Postal code field. The valid format is XXXXXX, where X is any
  773
+    digit and the first digit is not zero.
  774
+
  775
+.. class:: ru.forms.RUCountySelect
  776
+
  777
+    A ``Select`` widget that uses a list of Russian Counties as its choices.
  778
+
  779
+.. class:: ru.forms.RURegionSelect
  780
+
  781
+    A ``Select`` widget that uses a list of Russian Regions as its choices.
  782
+
  783
+.. class:: ru.forms.RUPassportNumberField
  784
+
  785
+    Russian internal passport number. The valid format is XXXX XXXXXX, where X
  786
+    is any digit.
  787
+
  788
+.. class:: ru.forms.RUAlienPassportNumberField
  789
+
  790
+    Russian alien's passport number. The valid format is XX XXXXXXX, where X
  791
+    is any digit.
  792
+
759 793
 Slovakia (``sk``)
760 794
 =================
761 795
 
0  localflavor/ru/__init__.py b/django/contrib/localflavor/ru/__init__.py
No changes.
148  tests/regressiontests/forms/localflavor/ru.py
... ...
@@ -0,0 +1,148 @@
  1
+from django.contrib.localflavor.ru.forms import *
  2
+ 
  3
+from utils import LocalFlavorTestCase
  4
+
  5
+
  6
+class RULocalFlavorTests(LocalFlavorTestCase):
  7
+
  8
+    def test_RUPassportNumberField(self):
  9
+        error = [u'Enter a passport number in the format XXXX XXXXXX.']
  10
+        valid = {
  11
+            '1981 211204': '1981 211204',
  12
+            '0305 967876': '0305 967876',
  13
+        }
  14
+        invalid = {
  15
+            '1981 2112044': error,
  16
+            '1981 23220': error,
  17
+            '9981211201': error,
  18
+        }
  19
+        self.assertFieldOutput(RUPassportNumberField, valid, invalid)
  20
+
  21
+    def test_RUAlienPassportNumberField(self):
  22
+        error = [u'Enter a passport number in the format XX XXXXXXX.']
  23
+        valid = {
  24
+            '19 8111204': '19 8111204',
  25
+            '03 0567876': '03 0567876',
  26
+        }
  27
+        invalid = {
  28
+            '198 1112044': error,
  29
+            '19 81123220': error,
  30
+            '99 812112': error,
  31
+        }
  32
+        self.assertFieldOutput(RUAlienPassportNumberField, valid, invalid)
  33
+
  34
+    def test_RUPostalCodeField(self):
  35
+        error = [u'Enter a postal code in the format XXXXXX.']
  36
+        valid = {
  37
+            '987654': '987654',
  38
+            '123456': '123456'
  39
+        }
  40
+        invalid = {
  41
+            '123 34': error,
  42
+            '1234567': error,
  43
+            '12345': error
  44
+        }
  45
+        self.assertFieldOutput(RUPostalCodeField, valid, invalid)
  46
+
  47
+    def test_RUCountySelect(self):
  48
+        f = RUCountySelect()
  49
+        out = u'''<select name="county">
  50
+<option value="Central Federal County">Central Federal County</option>
  51
+<option value="South Federal County">South Federal County</option>
  52
+<option value="North-West Federal County">North-West Federal County</option>
  53
+<option value="Far-East Federal County">Far-East Federal County</option>
  54
+<option value="Siberian Federal County">Siberian Federal County</option>
  55
+<option value="Ural Federal County">Ural Federal County</option>
  56
+<option value="Privolzhsky Federal County">Privolzhsky Federal County</option>
  57
+<option value="North-Caucasian Federal County">North-Caucasian Federal County</option>
  58
+</select>'''
  59
+        self.assertEqual(f.render('county', None), out)
  60
+
  61
+    def test_RURegionSelect(self):
  62
+        f = RURegionSelect()
  63
+        out = u'''<select name="region">
  64
+<option value="77">Moskva</option>
  65
+<option value="78">Saint-Peterburg</option>
  66
+<option value="50">Moskovskaya oblast&#39;</option>
  67
+<option value="01">Adygeya, Respublika</option>
  68
+<option value="02">Bashkortostan, Respublika</option>
  69
+<option value="03">Buryatia, Respublika</option>
  70
+<option value="04">Altay, Respublika</option>
  71
+<option value="05">Dagestan, Respublika</option>
  72
+<option value="06">Ingushskaya Respublika</option>
  73
+<option value="07">Kabardino-Balkarskaya Respublika</option>
  74
+<option value="08">Kalmykia, Respublika</option>
  75
+<option value="09">Karachaevo-Cherkesskaya Respublika</option>
  76
+<option value="10">Karelia, Respublika</option>
  77
+<option value="11">Komi, Respublika</option>
  78
+<option value="12">Mariy Ehl, Respublika</option>
  79
+<option value="13">Mordovia, Respublika</option>
  80
+<option value="14">Sakha, Respublika (Yakutiya)</option>
  81
+<option value="15">Severnaya Osetia, Respublika (Alania)</option>
  82
+<option value="16">Tatarstan, Respublika</option>
  83
+<option value="17">Tyva, Respublika (Tuva)</option>
  84
+<option value="18">Udmurtskaya Respublika</option>
  85
+<option value="19">Khakassiya, Respublika</option>
  86
+<option value="95">Chechenskaya Respublika</option>
  87
+<option value="21">Chuvashskaya Respublika</option>
  88
+<option value="22">Altayskiy Kray</option>
  89
+<option value="80">Zabaykalskiy Kray</option>
  90
+<option value="82">Kamchatskiy Kray</option>
  91
+<option value="23">Krasnodarskiy Kray</option>
  92
+<option value="24">Krasnoyarskiy Kray</option>
  93
+<option value="81">Permskiy Kray</option>
  94
+<option value="25">Primorskiy Kray</option>
  95
+<option value="26">Stavropol&#39;siyy Kray</option>
  96
+<option value="27">Khabarovskiy Kray</option>
  97
+<option value="28">Amurskaya oblast&#39;</option>
  98
+<option value="29">Arkhangel&#39;skaya oblast&#39;</option>
  99
+<option value="30">Astrakhanskaya oblast&#39;</option>
  100
+<option value="31">Belgorodskaya oblast&#39;</option>
  101
+<option value="32">Bryanskaya oblast&#39;</option>
  102
+<option value="33">Vladimirskaya oblast&#39;</option>
  103
+<option value="34">Volgogradskaya oblast&#39;</option>
  104
+<option value="35">Vologodskaya oblast&#39;</option>
  105
+<option value="36">Voronezhskaya oblast&#39;</option>
  106
+<option value="37">Ivanovskaya oblast&#39;</option>
  107
+<option value="38">Irkutskaya oblast&#39;</option>
  108
+<option value="39">Kaliningradskaya oblast&#39;</option>
  109
+<option value="40">Kaluzhskaya oblast&#39;</option>
  110
+<option value="42">Kemerovskaya oblast&#39;</option>
  111
+<option value="43">Kirovskaya oblast&#39;</option>
  112
+<option value="44">Kostromskaya oblast&#39;</option>
  113
+<option value="45">Kurganskaya oblast&#39;</option>
  114
+<option value="46">Kurskaya oblast&#39;</option>
  115
+<option value="47">Leningradskaya oblast&#39;</option>
  116
+<option value="48">Lipeckaya oblast&#39;</option>
  117
+<option value="49">Magadanskaya oblast&#39;</option>
  118
+<option value="51">Murmanskaya oblast&#39;</option>
  119
+<option value="52">Nizhegorodskaja oblast&#39;</option>
  120
+<option value="53">Novgorodskaya oblast&#39;</option>
  121
+<option value="54">Novosibirskaya oblast&#39;</option>
  122
+<option value="55">Omskaya oblast&#39;</option>
  123
+<option value="56">Orenburgskaya oblast&#39;</option>
  124
+<option value="57">Orlovskaya oblast&#39;</option>
  125
+<option value="58">Penzenskaya oblast&#39;</option>
  126
+<option value="60">Pskovskaya oblast&#39;</option>
  127
+<option value="61">Rostovskaya oblast&#39;</option>
  128
+<option value="62">Rjazanskaya oblast&#39;</option>
  129
+<option value="63">Samarskaya oblast&#39;</option>
  130
+<option value="64">Saratovskaya oblast&#39;</option>
  131
+<option value="65">Sakhalinskaya oblast&#39;</option>
  132
+<option value="66">Sverdlovskaya oblast&#39;</option>
  133
+<option value="67" selected="selected">Smolenskaya oblast&#39;</option>
  134
+<option value="68">Tambovskaya oblast&#39;</option>
  135
+<option value="69">Tverskaya oblast&#39;</option>
  136
+<option value="70">Tomskaya oblast&#39;</option>
  137
+<option value="71">Tul&#39;skaya oblast&#39;</option>
  138
+<option value="72">Tyumenskaya oblast&#39;</option>
  139
+<option value="73">Ul&#39;ianovskaya oblast&#39;</option>
  140
+<option value="74">Chelyabinskaya oblast&#39;</option>
  141
+<option value="76">Yaroslavskaya oblast&#39;</option>
  142
+<option value="79">Evreyskaya avtonomnaja oblast&#39;</option>
  143
+<option value="83">Neneckiy autonomnyy okrug</option>
  144
+<option value="86">Khanty-Mansiyskiy avtonomnyy okrug - Yugra</option>
  145
+<option value="87">Chukotskiy avtonomnyy okrug</option>
  146
+<option value="89">Yamalo-Neneckiy avtonomnyy okrug</option>
  147
+</select>'''
  148
+        self.assertEqual(f.render('region', '67'), out)
1  tests/regressiontests/forms/localflavortests.py
@@ -24,6 +24,7 @@
24 24
 from localflavor.pl import PLLocalFlavorTests
25 25
 from localflavor.pt import PTLocalFlavorTests
26 26
 from localflavor.ro import ROLocalFlavorTests
  27
+from localflavor.ru import RULocalFlavorTests
27 28
 from localflavor.se import SELocalFlavorTests
28 29
 from localflavor.sk import SKLocalFlavorTests
29 30
 from localflavor.tr import TRLocalFlavorTests
1  tests/regressiontests/forms/tests/__init__.py
@@ -38,6 +38,7 @@
38 38
     PLLocalFlavorTests,
39 39
     PTLocalFlavorTests,
40 40
     ROLocalFlavorTests,
  41
+    RULocalFlavorTests,
41 42
     SELocalFlavorTests,
42 43
     SKLocalFlavorTests,
43 44
     TRLocalFlavorTests,

0 notes on commit e1f7bc0

Please sign in to comment.
Something went wrong with that request. Please try again.