Spanish National Identification Number Field (DNI)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def fiscal_letter(fiscal_num=None):   
    """return the correct letter for the fiscal_num param"""
    if fiscal_num:
        result = fiscal_num%23
        letters='TRWAGMYFPDXBNJZSQVHLCKE'
        return letters[result]   
    return fiscal_num

def is_valid_id(dni_type, number):
    """"""
    is_valid = False
    if dni_type == 'nif' :
        if number[0:8].isdigit() and len(number) == 9:                   
            letter = fiscal_letter(int(number[0:8]))
            is_valid = number[8].upper() == letter
    
    elif dni_type == 'nie':
        correct_length = len(number) == 10 or len(number) == 9
        correct_letter = number[0].upper() == 'X' or number[0].upper() == 'Y'
        correct_digits = number[1:len(number)-1].isdigit()

        if correct_digits and correct_length and correct_letter:                   
            letter = fiscal_letter(int(number[1:-1]))
            is_valid = number[-1].upper() == letter                               
    else:
        is_valid=True
    
    return is_valid

#
#
from django.core.validators import EMPTY_VALUES
from django.forms import ValidationError

class DNIField(CharField):
    default_error_messages = {
       'invalid': _('Please, enter a valid DNI'),
    }

    def clean(self, value):
        super(CharField, self).clean(value)
        if value in EMPTY_VALUES:
               return u''

        first_letter = value[0]
        type_id = "nif"
        try:
           int(first_letter)
        except ValueError:
           type_id = "nie"
        
        if is_valid_id(type_id, value):
             return value

        raise ValidationError(self.error_messages['invalid'])

More like this

  1. UKPhoneNumberField GB v2 by g1smd 9 months, 2 weeks ago
  2. Password Validation - Require Letters and Numbers - no regex by watchedman 1 year, 9 months ago
  3. UKPhoneNumberField GB v3 (improved) by g1smd 9 months, 2 weeks ago
  4. CodeLookupField by girasquid 4 years ago
  5. boostrap prepend-input for widgets by DimmuR 8 months, 3 weeks ago

Comments

esauro (on June 16, 2011):

Congrats for publishing a snippet and share your work with the community. However, wasn't this solved with spanish localflavor?

#

cues7a (on June 16, 2011):

Oh, you are right!

I didn't know the field was already done in local flavours module,

Thank you.

#

(Forgotten your password?)