From 94954862d5e6c03b66aaa9775e44fa1d0c05e20f Mon Sep 17 00:00:00 2001 From: Joseph Kocherhans Date: Fri, 26 Oct 2007 20:35:16 +0000 Subject: [PATCH] newforms-admin: Added some files missing from [6613] git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6614 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/templatetags/cache.py | 57 +++ django/utils/checksums.py | 22 ++ tests/regressiontests/forms/localflavor/es.py | 343 ++++++++++++++++++ 3 files changed, 422 insertions(+) create mode 100644 django/templatetags/cache.py create mode 100644 django/utils/checksums.py create mode 100644 tests/regressiontests/forms/localflavor/es.py diff --git a/django/templatetags/cache.py b/django/templatetags/cache.py new file mode 100644 index 0000000000..4436b15d6e --- /dev/null +++ b/django/templatetags/cache.py @@ -0,0 +1,57 @@ +from django.template import Library, Node, TemplateSyntaxError +from django.template import resolve_variable +from django.core.cache import cache +from django.utils.encoding import force_unicode + +register = Library() + +class CacheNode(Node): + def __init__(self, nodelist, expire_time, fragment_name, vary_on): + self.nodelist = nodelist + self.expire_time = expire_time + self.fragment_name = fragment_name + self.vary_on = vary_on + + def render(self, context): + # Build a unicode key for this fragment and all vary-on's. + cache_key = u':'.join([self.fragment_name] + \ + [force_unicode(resolve_variable(var, context)) for var in self.vary_on]) + value = cache.get(cache_key) + if value is None: + value = self.nodelist.render(context) + cache.set(cache_key, value, self.expire_time) + return value + +def do_cache(parser, token): + """ + This will cache the contents of a template fragment for a given amount + of time. + + Usage:: + + {% load cache %} + {% cache [expire_time] [fragment_name] %} + .. some expensive processing .. + {% endcache %} + + This tag also supports varying by a list of arguments:: + + {% load cache %} + {% cache [expire_time] [fragment_name] [var1] [var2] .. %} + .. some expensive processing .. + {% endcache %} + + Each unique set of arguments will result in a unique cache entry. + """ + nodelist = parser.parse(('endcache',)) + parser.delete_first_token() + tokens = token.contents.split() + if len(tokens) < 3: + raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0]) + try: + expire_time = int(tokens[1]) + except ValueError: + raise TemplateSyntaxError(u"First argument to '%r' must be an integer (got '%s')." % (tokens[0], tokens[1])) + return CacheNode(nodelist, expire_time, tokens[2], tokens[3:]) + +register.tag('cache', do_cache) diff --git a/django/utils/checksums.py b/django/utils/checksums.py new file mode 100644 index 0000000000..970f563f38 --- /dev/null +++ b/django/utils/checksums.py @@ -0,0 +1,22 @@ +""" +Common checksum routines (used in multiple localflavor/ cases, for example). +""" + +__all__ = ['luhn',] + +LUHN_ODD_LOOKUP = (0, 2, 4, 6, 8, 1, 3, 5, 7, 9) # sum_of_digits(index * 2) + +def luhn(candidate): + """ + Checks a candidate number for validity according to the Luhn + algorithm (used in validation of, for example, credit cards). + Both numeric and string candidates are accepted. + """ + if not isinstance(candidate, basestring): + candidate = str(candidate) + try: + evens = sum([int(c) for c in candidate[-1::-2]]) + odds = sum([LUHN_ODD_LOOKUP[int(c)] for c in candidate[-2::-2]]) + return ((evens + odds) % 10 == 0) + except ValueError: # Raised if an int conversion fails + return False diff --git a/tests/regressiontests/forms/localflavor/es.py b/tests/regressiontests/forms/localflavor/es.py new file mode 100644 index 0000000000..f149aa9cbe --- /dev/null +++ b/tests/regressiontests/forms/localflavor/es.py @@ -0,0 +1,343 @@ +# -*- coding: utf-8 -*- +# Tests for the contrib/localflavor/ ES form fields. + +tests = r""" +# ESPostalCodeField ############################################################## + +ESPostalCodeField validates that data is a five-digit spanish postal code. +>>> from django.contrib.localflavor.es.forms import ESPostalCodeField +>>> f = ESPostalCodeField() +>>> f.clean('08028') +u'08028' +>>> f.clean('28080') +u'28080' +>>> f.clean('53001') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('0801') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('080001') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('00999') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('08 01') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('08A01') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = ESPostalCodeField(required=False) +>>> f.clean('08028') +u'08028' +>>> f.clean('28080') +u'28080' +>>> f.clean('53001') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('0801') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('080001') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('00999') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('08 01') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('08A01') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] +>>> f.clean('') +u'' + +# ESPhoneNumberField ############################################################## + +ESPhoneNumberField validates that data is a nine-digit spanish phone number. +>>> from django.contrib.localflavor.es.forms import ESPhoneNumberField +>>> f = ESPhoneNumberField() +>>> f.clean('650010101') +u'650010101' +>>> f.clean('931234567') +u'931234567' +>>> f.clean('800123123') +u'800123123' +>>> f.clean('555555555') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'] +>>> f.clean('789789789') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'] +>>> f.clean('99123123') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'] +>>> f.clean('9999123123') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = ESPhoneNumberField(required=False) +>>> f.clean('650010101') +u'650010101' +>>> f.clean('931234567') +u'931234567' +>>> f.clean('800123123') +u'800123123' +>>> f.clean('555555555') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'] +>>> f.clean('789789789') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'] +>>> f.clean('99123123') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'] +>>> f.clean('9999123123') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'] +>>> f.clean('') +u'' + +# ESIdentityCardNumberField ############################################################## + +ESIdentityCardNumberField validates that data is a identification spanish code for companies or individuals (CIF, NIF or NIE). +>>> from django.contrib.localflavor.es.forms import ESIdentityCardNumberField +>>> f = ESIdentityCardNumberField() +>>> f.clean('78699688J') +'78699688J' +>>> f.clean('78699688-J') +'78699688J' +>>> f.clean('78699688 J') +'78699688J' +>>> f.clean('78699688 j') +'78699688J' +>>> f.clean('78699688T') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for NIF.'] +>>> f.clean('X0901797J') +'X0901797J' +>>> f.clean('X-6124387-Q') +'X6124387Q' +>>> f.clean('X 0012953 G') +'X0012953G' +>>> f.clean('x-3287690-r') +'X3287690R' +>>> f.clean('t-03287690r') +'T03287690R' +>>> f.clean('X-03287690') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid NIF, NIE, or CIF.'] +>>> f.clean('X-03287690-T') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for NIE.'] +>>> f.clean('B38790911') +'B38790911' +>>> f.clean('B-3879091A') +'B3879091A' +>>> f.clean('B 38790917') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for CIF.'] +>>> f.clean('B 38790911') +'B38790911' +>>> f.clean('P-3900800-H') +'P3900800H' +>>> f.clean('P 39008008') +'P39008008' +>>> f.clean('C-28795565') +'C28795565' +>>> f.clean('C 2879556E') +'C2879556E' +>>> f.clean('C28795567') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for CIF.'] +>>> f.clean('I38790911') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid NIF, NIE, or CIF.'] +>>> f.clean('78699688-2') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid NIF, NIE, or CIF.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = ESIdentityCardNumberField(required=False) +>>> f.clean('78699688J') +'78699688J' +>>> f.clean('78699688-J') +'78699688J' +>>> f.clean('78699688 J') +'78699688J' +>>> f.clean('78699688 j') +'78699688J' +>>> f.clean('78699688T') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for NIF.'] +>>> f.clean('X0901797J') +'X0901797J' +>>> f.clean('X-6124387-Q') +'X6124387Q' +>>> f.clean('X 0012953 G') +'X0012953G' +>>> f.clean('x-3287690-r') +'X3287690R' +>>> f.clean('t-03287690r') +'T03287690R' +>>> f.clean('X-03287690') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid NIF, NIE, or CIF.'] +>>> f.clean('X-03287690-T') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for NIE.'] +>>> f.clean('B38790911') +'B38790911' +>>> f.clean('B-3879091A') +'B3879091A' +>>> f.clean('B 38790917') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for CIF.'] +>>> f.clean('B 38790911') +'B38790911' +>>> f.clean('P-3900800-H') +'P3900800H' +>>> f.clean('P 39008008') +'P39008008' +>>> f.clean('C-28795565') +'C28795565' +>>> f.clean('C 2879556E') +'C2879556E' +>>> f.clean('C28795567') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for CIF.'] +>>> f.clean('I38790911') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid NIF, NIE, or CIF.'] +>>> f.clean('78699688-2') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid NIF, NIE, or CIF.'] +>>> f.clean('') +u'' + +# ESCCCField ############################################################## + +ESCCCField validates that data is a spanish bank account number (codigo cuenta cliente). + +>>> from django.contrib.localflavor.es.forms import ESCCCField +>>> f = ESCCCField() +>>> f.clean('20770338793100254321') +'20770338793100254321' +>>> f.clean('2077 0338 79 3100254321') +'2077 0338 79 3100254321' +>>> f.clean('2077-0338-79-3100254321') +'2077-0338-79-3100254321' +>>> f.clean('2077.0338.79.3100254321') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.'] +>>> f.clean('2077-0338-78-3100254321') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for bank account number.'] +>>> f.clean('2077-0338-89-3100254321') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for bank account number.'] +>>> f.clean('2077-03-3879-3100254321') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = ESCCCField(required=False) +>>> f.clean('20770338793100254321') +'20770338793100254321' +>>> f.clean('2077 0338 79 3100254321') +'2077 0338 79 3100254321' +>>> f.clean('2077-0338-79-3100254321') +'2077-0338-79-3100254321' +>>> f.clean('2077.0338.79.3100254321') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.'] +>>> f.clean('2077-0338-78-3100254321') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for bank account number.'] +>>> f.clean('2077-0338-89-3100254321') +Traceback (most recent call last): +... +ValidationError: [u'Invalid checksum for bank account number.'] +>>> f.clean('2077-03-3879-3100254321') +Traceback (most recent call last): +... +ValidationError: [u'Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.'] +>>> f.clean('') +u'' + +# ESRegionSelect ############################################################## + +ESRegionSelect is a Select widget that uses a list of Spain regions as its choices. +>>> from django.contrib.localflavor.es.forms import ESRegionSelect +>>> w = ESRegionSelect() +>>> w.render('regions', 'CT') +u'' + +# ESProvincenSelect ############################################################## + +ESProvinceSelect is a Select widget that uses a list of Spain provinces as its choices. +>>> from django.contrib.localflavor.es.forms import ESProvinceSelect +>>> w = ESProvinceSelect() +>>> w.render('provinces', '08') +u'' + +""" +