Hello all,

I have a fairly complex schema and a need to perform moderately complex 
inter-field validation. As far as I can tell, the complex validation must 
be performed at the lowest SchemaNode in the structure that is a parent of 
both fields. That's fine, but I cannot see how to attach the resulting 
errors to the actual fields themselves (so that when I render the error 
form the error messages appear with the fields).

Here's an illustrative test schema. The idea is that if field 
c.value_string is present, then field b.a_list.n.value_string is required 
(for all n >= 0).

import colander
import deform.widget

OPTIONAL=colander.null

class A(colander.MappingSchema):
    value_string = colander.SchemaNode(colander.String(), missing=OPTIONAL)
    value_int = colander.SchemaNode(colander.Integer())
    value_bool = colander.SchemaNode(colander.Boolean())

class AList(colander.SequenceSchema):
    a = A()

class B(colander.MappingSchema):
    a_list = AList()

class C(colander.MappingSchema):
    value_string = colander.SchemaNode(colander.String(), missing=OPTIONAL)

class MySchema(colander.MappingSchema):
    b = B()
    c = C()
    def validator(self, node, data):
        if data["c"]["value_string"] is not colander.null:
            for (pos, a) in enumerate(data["b"]["a_list"]):
                if a["value_string"] is colander.null:
                    exc_node = node["b"]["a_list"]["a"]
                    exc = colander.Invalid(exc_node)
                    exc["value_string"] = "Required"
                    # Tried this but it won't fly
                    # exc["b"]["a_list"][pos]["value_string"] = "Required"
                    raise exc

initial_data = {
    "c" : { "value_string" : "x" },
    "b" : { "a_list" : [{
        "value_string" : colander.null,
        "value_int" : 1,
        "value_bool" : False,
    }]}
}


FWIW, this is the pyramid view that handles the form requests (it's pretty 
vanilla and doesn't add much to the question, although we are using cheetah 
templates to render the widgets):

class DeformTestView(object):
    def __init__(self, context, request):
        self.context = context
        self.request = request

    def __call__(self):
        schema = portal.test.deform.test_schema.MySchema()
        renderer = portal.deform.util.cheetah_renderer
        submit_btn = deform.Button(title="Submit", css_class="span2")
        submit_btn.id = "submit_button"
        submit_btn.href = pyramid.url.resource_url(self.context, 
self.request)
        submit_btn.newwindow = False
        form = deform.Form(
            schema,
            formid="data_entry_form",  # default=deform, which breaks 
deform.js
            method="POST",
            renderer=renderer,
            buttons=[submit_btn],
            )
        form.widget.css_class = "deform small form-horizontal condensed"

        if self.request.method == "GET":
            return dict(
                view=self,
                
deform_form=form.render(portal.test.deform.test_schema.initial_data)
                )

        if self.request.method == "POST":
            try:
                form_data = form.validate(self.request.POST.items())
            except deform.ValidationFailure as error_form:
                print "DeformTestView.__call__: validation exception: %s" % 
str(error_form.error)
                return dict (
                    view=self,
                    deform_form=error_form.render(),
                    )

        return dict(
            view=self,
            deform_form=form.render(form_data)
            )

The print in the POST case emits this:
DeformTestView.__call__: validation exception: {'a.value_string': 
'Required'}

which is not particularly useful; I'd like it to look more like:
DeformTestView.__call__: validation exception: {'b.a_list.0.value_string': 
'Required'}

but I cannot see what to do to make that happen.

Thanks,
Alistair

-- 
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/pylons-discuss?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to