successfully ported everything to a flesh shabti template. shortnames work now,...
[zzz-floof.git] / floof / forms / validators / unique.py
diff --git a/floof/forms/validators/unique.py b/floof/forms/validators/unique.py
new file mode 100644 (file)
index 0000000..4fb3c8f
--- /dev/null
@@ -0,0 +1,52 @@
+from formencode import *
+from formencode import validators 
+import pylons
+
+_ = validators._ # dummy translation string
+
+# Custom schemas
+
+class FilteringSchema(Schema):
+    "Schema with extra fields filtered by default"
+    filter_extra_fields = True
+    allow_extra_fields = True
+
+# Model-based validators
+
+class Unique(validators.FancyValidator):
+    
+    """
+    Checks if given value is unique to the model.Will check the state: if state object
+    is the same as the instance, or the state contains a property with the same name
+    as the context name. For example:
+    
+    validator = validators.Unique(model.NewsItem, "title", context_name="news_item")
+    
+    This will check if there is an existing instance with the same "title". If there
+    is a matching instance, will check if the state passed into the validator is the
+    same instance, or if the state contains a property "news_item" which is the same
+    instance.
+    """
+    
+    __unpackargs__ = ('model', 'attr', "model_name", "context_name", "attribute_name")
+    messages = {
+        'notUnique' : _("%(modelName)s already exists with this %(attrName)s"),
+    }
+    
+    model_name = "Item"
+    attribute_name = None
+    context_name = None
+    
+    def validate_python(self, value, state):
+        instance = self.model.get_by(**{self.attr : value})
+        if instance:
+            context_name = self.context_name or self.model.__name__.lower()
+            if state != instance and \
+                getattr(state, context_name, None) != instance:
+                attr_name = self.attribute_name or self.attr
+                raise Invalid(self.message('notUnique', state, 
+                                           modelName=self.model_name,
+                                           attrName=attr_name), 
+                              value, state)
+validators.Unique = Unique