For URLs I just define a convention and use that everywhere. But you have to tell Pyramid to not handle those requests, so I have the following:
def automore(request, elements, kw):
# this is for adding the more kwargs for backbone urls
kw.setdefault('more', ())
return elements, kw
config.add_route('index', '/*more', pregenerator=automore)
This tells pyramid to send all requests to the index route, we do this because backbone.js is actually going to handle the routing.
Then for form submission I actually build RESTful webservices in pyramid and on form submit I pass my form data to a backbone model and then save that out, and use colander to actually validate the data coming in:
map_form_to_model: function(data, model) {
model.off("change");
for(var i=0; i < data.length; i++) {
var name = data[i].name;
var value = data[i].value;
var current_value = model.get(name);
if (value != current_value) {
model.set(name, value);
}
}
},
save_model: function(e) {
e.preventDefault();
if (this.model != undefined) {
var me = this;
var data = me.$("form").serializeArray();
map_form_to_model(data, me.model);
me.model.save({
error: function(e) {
console.log(e);
}
})
}
},
and the server side of something like that:
@json_result
def get_user(self):
user = None
try:
pk = self.request.matchdict.get("user_pk")
user = self.manager.get_by_pk(pk)
except DataError:
pass
if not user:
return HTTPNotFound()
return user.serialize()
@json_result
def save_user(self):
data = json.loads(self.request.body)
schema = ProfileSchema()
try:
cstruct = schema.deserialize(data)
except colander.Invalid, e:
return HTTPBadRequest(e.asdict())
try:
pk = self.request.matchdict.get("user_pk")
user = self.manager.get_by_pk(pk)
except DataError:
pass
if not user:
return HTTPNotFound()
map_dict_to_obj(cstruct, user)
self.db.add(user)
return {'success': True}