4fb3c8f1553e07d740983af6d49e07a689e4f112
[zzz-floof.git] / floof / forms / validators / unique.py
1 from formencode import *
2 from formencode import validators
3 import pylons
4
5 _ = validators._ # dummy translation string
6
7 # Custom schemas
8
9 class FilteringSchema(Schema):
10 "Schema with extra fields filtered by default"
11 filter_extra_fields = True
12 allow_extra_fields = True
13
14 # Model-based validators
15
16 class Unique(validators.FancyValidator):
17
18 """
19 Checks if given value is unique to the model.Will check the state: if state object
20 is the same as the instance, or the state contains a property with the same name
21 as the context name. For example:
22
23 validator = validators.Unique(model.NewsItem, "title", context_name="news_item")
24
25 This will check if there is an existing instance with the same "title". If there
26 is a matching instance, will check if the state passed into the validator is the
27 same instance, or if the state contains a property "news_item" which is the same
28 instance.
29 """
30
31 __unpackargs__ = ('model', 'attr', "model_name", "context_name", "attribute_name")
32 messages = {
33 'notUnique' : _("%(modelName)s already exists with this %(attrName)s"),
34 }
35
36 model_name = "Item"
37 attribute_name = None
38 context_name = None
39
40 def validate_python(self, value, state):
41 instance = self.model.get_by(**{self.attr : value})
42 if instance:
43 context_name = self.context_name or self.model.__name__.lower()
44 if state != instance and \
45 getattr(state, context_name, None) != instance:
46 attr_name = self.attribute_name or self.attr
47 raise Invalid(self.message('notUnique', state,
48 modelName=self.model_name,
49 attrName=attr_name),
50 value, state)
51
52 validators.Unique = Unique