Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from ferris.core import inflector, autoadmin
- from ferris.core.forms import model_form
- from ferris.components.flash_messages import FlashMessages
- (autoadmin) # load autoadmin here, if any controller use scaffold it'll be included and initialized
- [docs]class Scaffolding(object): """ Scaffolding Component """ def __init__(self, controller): self.controller = controller self._init_meta() self._init_flash() def _init_flash(self): if not FlashMessages in self.controller.Meta.components: self.controller.components['flash_messages'] = FlashMessages(self.controller) def _init_meta(self): """ Constructs the controller's scaffold property from the controller's Scaffold class. If the controller doens't have a scaffold, uses the automatic one. """ if not hasattr(self.controller.Meta, 'Model'): _load_model(self.controller) if not hasattr(self.controller, 'Scaffold'): setattr(self.controller, 'Scaffold', Scaffold) if not issubclass(self.controller.Scaffold, Scaffold): self.controller.Scaffold = type('Scaffold', (self.controller.Scaffold, Scaffold), {}) setattr(self.controller, 'scaffold', self.controller.Scaffold(self.controller)) self.controller.events.template_names += self._on_template_names self.controller.events.before_render += self._on_before_render self.controller.events.scaffold_before_parse += self._on_scaffold_before_parse def _on_scaffold_before_parse(self, controller): if not hasattr(controller.meta, 'Form') or not controller.meta.Form: controller.meta.Form = controller.scaffold.ModelForm def _on_template_names(self, controller, templates): """Injects scaffold templates into the template list""" controller, prefix, action, ext = self.controller.route.name, self.controller.route.prefix, self.controller.route.action, self.controller.meta.view.template_ext # Try the prefix template first if prefix: templates.append('scaffolding/%s_%s.%s' % (prefix, action, ext)) # Then try the non-prefix one. templates.append('scaffolding/%s.%s' % (action, ext)) def _on_before_render(self, controller): controller.context['scaffolding'] = { 'name': controller.name, 'proper_name': controller.proper_name, 'title': controller.scaffold.title, 'plural': controller.scaffold.plural, 'singular': controller.scaffold.singular, 'form_action': controller.scaffold.form_action, 'form_encoding': controller.scaffold.form_encoding, 'display_properties': controller.scaffold.display_properties, 'layouts': controller.scaffold.layouts, 'navigation': controller.scaffold.navigation }
- class Scaffold(object):
- """
- Scaffold Meta Object Base Class
- """
- def __init__(self, controller):
- defaults = dict(
- query_factory=default_query_factory,
- create_factory=default_create_factory,
- title=inflector.titleize(controller.proper_name),
- plural=inflector.underscore(controller.name),
- singular=inflector.underscore(inflector.singularize(controller.name)),
- ModelForm=model_form(controller.meta.Model),
- display_properties=sorted([name for name, property in controller.meta.Model._properties.items()]),
- redirect=controller.uri(action='list') if controller.uri_exists(action='list') else None,
- form_action=None,
- form_encoding='application/x-www-form-urlencoded',
- flash_messages=True,
- layouts={
- None: 'layouts/default.html',
- 'admin': 'layouts/admin.html'
- },
- navigation={}
- )
- for k, v in defaults.iteritems():
- if not hasattr(self, k):
- setattr(self, k, v)
- # Default Factories
- def default_query_factory(controller):
- """
- The default factory just returns Model.query(), sorted by created if it's available.
- """
- Model = controller.meta.Model
- query = Model.query()
- if 'created' in Model._properties and Model._properties['created']._indexed:
- query = query.order(-Model.created)
- return query
- def default_create_factory(controller):
- """
- The default create factory just calls Model()
- """
- return controller.meta.Model()
- def delegate_query_factory(controller):
- """
- Calls Model.Meta.query_factory or Model.list or Model.query.
- """
- Model = controller.Meta.Model
- if hasattr(Model.Meta, 'query_factory'):
- return Model.Meta.query_factory(controller)
- if hasattr(Model, 'list'):
- return Model.list(controller)
- return default_query_factory(controller)
- def delegate_create_factory(controller):
- """
- Calls Model.Meta.create_factory or Model.create or the Model constructor.
- """
- Model = controller.Meta.Model
- if hasattr(Model.Meta, 'create_factory'):
- return Model.Meta.create_factory(controller)
- if hasattr(Model, 'create'):
- return Model.create(controller)
- return default_create_factory(controller)
- # Utility Functions
- def _load_model(controller):
- import_form_base = '.'.join(controller.__module__.split('.')[:-2])
- # Attempt to import the model automatically
- model_name = inflector.singularize(controller.__class__.__name__)
- try:
- module = __import__('%s.models.%s' % (import_form_base, inflector.underscore(model_name)), fromlist=['*'])
- setattr(controller.Meta, 'Model', getattr(module, model_name))
- except (ImportError, AttributeError):
- raise RuntimeError("Scaffold coudn't automatically determine a model class for controller %s, please assign it a Meta.Model class variable." % controller.__class__.__name__)
- def _flash(controller, *args, **kwargs):
- if 'flash_messages' in controller.components and controller.scaffold.flash_messages:
- controller.components.flash_messages(*args, **kwargs)
- # controller Methods
- [docs]def list(controller): controller.context.set(**{ controller.scaffold.plural: controller.scaffold.query_factory(controller) })
- [docs]def view(controller, key): item = controller.util.decode_key(key).get() if not item: return 404 controller.context.set(**{ controller.scaffold.singular: item})
- def save_callback(controller, item, parser):
- parser.update(item)
- controller.events.scaffold_before_save(controller=controller, container=parser.container, item=item)
- item.put()
- controller.events.scaffold_after_save(controller=controller, container=parser.container, item=item)
- def parser_action(controller, item, callback=save_callback):
- controller.events.scaffold_before_parse(controller=controller)
- parser = controller.parse_request(fallback=item)
- if controller.request.method in ('PUT', 'POST', 'PATCH'):
- if parser.validate():
- controller.events.scaffold_before_apply(controller=controller, container=parser.container, item=item)
- callback(controller, item, parser)
- controller.events.scaffold_after_apply(controller=controller, container=parser.container, item=item)
- controller.context.set(**{
- controller.scaffold.singular: item})
- _flash(controller, 'The item was saved successfully', 'success')
- if controller.scaffold.redirect:
- return controller.redirect(controller.scaffold.redirect)
- else:
- controller.context['errors'] = parser.errors
- _flash(controller, 'There were errors on the form, please correct and try again.', 'error')
- controller.context.set(**{
- 'form': parser.container,
- controller.scaffold.singular: item})
- [docs]def add(controller): item = controller.scaffold.create_factory(controller) return parser_action(controller, item)
- [docs]def edit(controller, key): item = controller.util.decode_key(key).get() if not item: return 404 return parser_action(controller, item)
- [docs]def delete(controller, key): key = controller.util.decode_key(key) controller.events.scaffold_before_delete(controller=controller, key=key) key.delete() controller.events.scaffold_after_delete(controller=controller, key=key) _flash(controller, 'The item was deleted successfully', 'success') if controller.scaffold.redirect: return controller.redirect(controller.scaffold.redirect)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement