Merge branch 'penfield' of git://github.com/kgodey/philo into penfield
[philo.git] / validators.py
1 from django.core.exceptions import ValidationError
2 from django.utils.translation import ugettext_lazy as _
3
4
5 class TreeParentValidator(object):
6         """
7         constructor takes instance and parent_attr, where instance is the model
8         being validated and parent_attr is where to look on that parent for the
9         comparison.
10         """
11         #message = _("A tree element can't be its own parent.")
12         code = 'invalid'
13         
14         def __init__(self, instance, parent_attr=None, message=None, code=None):
15                 self.instance = instance
16                 self.parent_attr = parent_attr
17                 self.static_message = message
18                 if code is not None:
19                         self.code = code
20         
21         def __call__(self, value):
22                 """
23                 Validates that the self.instance is not found in the parent tree of
24                 the node given as value.
25                 """
26                 parent = value
27                 
28                 while parent:
29                         comparison=self.get_comparison(parent)
30                         if comparison == self.instance:
31                                 # using (self.message, code=self.code) results in the admin interface
32                                 # screwing with the error message and making it be 'Enter a valid value'
33                                 raise ValidationError(self.message)
34                         parent=parent.parent
35         
36         def get_comparison(self, parent):
37                 if self.parent_attr and hasattr(parent, self.parent_attr):
38                         return getattr(parent, self.parent_attr)
39                 
40                 return parent
41         
42         def get_message(self):
43                 return self.static_message or _(u"A %s can't be its own parent." % self.instance.__class__.__name__)
44         message = property(get_message)
45         
46 class TreePositionValidator(object):
47         code = 'invalid'
48         
49         def __init__(self, parent, slug, obj_class, message=None, code=None):
50                 self.parent = parent
51                 self.slug = slug
52                 self.obj_class = obj_class
53                 self.static_message = message
54                         
55                 if code is not None:
56                         self.code = code
57         
58         def __call__(self, value):
59                 """
60                 Validates that there is no obj of obj_class with the same position
61                 as the compared obj (value) but a different id.
62                 """
63                 if not isinstance(value, self.obj_class):
64                         raise ValidationError(_(u"The value must be an instance of %s." % self.obj_class.__name__))
65                 
66                 try:
67                         obj = self.obj_class.objects.get(slug=self.slug, parent=self.parent)
68                         
69                         if obj.id != value.id:
70                                 raise ValidationError(self.message)
71                                 
72                 except self.obj_class.DoesNotExist:
73                         pass
74         
75         def get_message(self):
76                 return self.static_message or _(u"A %s with that path (parent and slug) already exists." % self.obj_class.__name__)
77         message = property(get_message)