Project

General

Profile

Download (3.8 KB) Statistics
| Branch: | Tag: | Revision:

calebasse / calebasse / models.py @ adfb9ea4

1
# -*- coding: utf-8 -*-
2

    
3
from django.db import models
4
from django.db.models import fields
5
from django import forms
6
from localflavor.fr.forms import FRPhoneNumberField, FRZipCodeField
7
from django.utils.text import capfirst
8

    
9

    
10
class BaseModelMixin(object):
11
    def __repr__(self):
12
        return '<%s %s %r>' % (self.__class__.__name__, self.id, unicode(self))
13

    
14

    
15
class PhoneNumberField(models.CharField):
16
    def __init__(self, *args, **kwargs):
17
        kwargs['max_length'] = 20
18
        super(PhoneNumberField, self).__init__(*args, **kwargs)
19

    
20
    def formfield(self, **kwargs):
21
        default = { 'form_class': FRPhoneNumberField }
22
        default.update(kwargs)
23
        return super(PhoneNumberField, self).formfield(**kwargs)
24

    
25

    
26
class ZipCodeField(models.CharField):
27
    def __init__(self, **kwargs):
28
        kwargs['max_length'] = 5
29
        super(ZipCodeField, self).__init__(**kwargs)
30

    
31
    def formfield(self, **kwargs):
32
        default = { 'form_class': FRZipCodeField }
33
        default.update(kwargs)
34
        return super(ZipCodeField, self).formfield(**kwargs)
35

    
36
class WeekRankField(models.PositiveIntegerField):
37
    '''Map a list of integers to its encoding as a binary number'''
38
    __metaclass__ = models.SubfieldBase
39

    
40
    def __init__(self, **kwargs):
41
        kwargs['blank'] = True
42
        kwargs['null'] = True
43
        super(WeekRankField, self).__init__(**kwargs)
44

    
45
    def to_python(self, value):
46
        if isinstance(value, list):
47
            if value:
48
                try:
49
                    value = map(int, value)
50
                except ValueError:
51
                    raise forms.ValidationError('value must be a sequence of value coercible to integers')
52
                if any((i < 0 or i > 4 for i in value)):
53
                    raise forms.ValidationError('value must be a list of integers between 0 and 4')
54
                return map(int, set(value))
55
            else:
56
                return None
57
        value = super(WeekRankField, self).to_python(value)
58
        if value is None:
59
            return None
60
        try:
61
            value = int(value)
62
        except ValueError:
63
            raise forms.ValidationError('value must be convertible to an integer')
64
        if value < 0 or value >= 64:
65
            raise forms.ValidationError('value must be between 0 and 64')
66
        return tuple((i for i in range(0, 5) if (1 << i) & value))
67

    
68

    
69
    def clean(self, value, model_instance):
70
        """
71
        Convert the value's type and run validation. Validation errors
72
        from to_python and validate are propagated. The correct value is
73
        returned if no error is raised.
74
        """
75
        value = self.to_python(value)
76
        [self.validate(v, model_instance) for v in value]
77
        self.run_validators(value)
78
        return value
79

    
80

    
81
    def get_prep_lookup(self, lookup_type, value):
82
        if lookup_type in ('exact', 'in'):
83
            s = set(((1 << v) | i for v in value for i in range(0, 64)))
84
            return s
85
        elif lookup_type == 'range':
86
            value = sorted(value)
87
            return set(((1 << v) | i for v in range(value[0], value[1]) for i in range(0, 64)))
88
        else:
89
            return fields.Field.get_prep_lookup(self, lookup_type, value)
90

    
91

    
92
    def get_prep_value(self, value):
93
        if value:
94
            x = sum((1 << int(i) for i in value))
95
            return x
96
        else:
97
            return None
98

    
99
    def formfield(self, **kwargs):
100
        defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 
101
                    'help_text': self.help_text, 'choices': self.get_choices(include_blank=False)}
102
        if self.has_default():
103
            defaults['initial'] = self.get_default()
104
        defaults.update(kwargs)
105
        return forms.MultipleChoiceField(**defaults)
106

    
107
from south.modelsinspector import add_introspection_rules
108
add_introspection_rules([], ["^calebasse\.models\..*Field"])
109

    
(10-10/17)