Advertisement
johnmahugu

python - ferris crud scaffold

Jul 23rd, 2015
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.09 KB | None | 0 0
  1. from ferris.core import inflector, autoadmin
  2. from ferris.core.forms import model_form
  3. from ferris.components.flash_messages import FlashMessages
  4. (autoadmin)  # load autoadmin here, if any controller use scaffold it'll be included and initialized
  5.  
  6.  
  7. [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 }
  8.  
  9. class Scaffold(object):
  10.     """
  11.    Scaffold Meta Object Base Class
  12.    """
  13.     def __init__(self, controller):
  14.  
  15.         defaults = dict(
  16.             query_factory=default_query_factory,
  17.             create_factory=default_create_factory,
  18.             title=inflector.titleize(controller.proper_name),
  19.             plural=inflector.underscore(controller.name),
  20.             singular=inflector.underscore(inflector.singularize(controller.name)),
  21.             ModelForm=model_form(controller.meta.Model),
  22.             display_properties=sorted([name for name, property in controller.meta.Model._properties.items()]),
  23.             redirect=controller.uri(action='list') if controller.uri_exists(action='list') else None,
  24.             form_action=None,
  25.             form_encoding='application/x-www-form-urlencoded',
  26.             flash_messages=True,
  27.             layouts={
  28.                 None: 'layouts/default.html',
  29.                 'admin': 'layouts/admin.html'
  30.             },
  31.             navigation={}
  32.         )
  33.  
  34.         for k, v in defaults.iteritems():
  35.             if not hasattr(self, k):
  36.                 setattr(self, k, v)
  37.  
  38.  
  39. # Default Factories
  40.  
  41.  
  42. def default_query_factory(controller):
  43.     """
  44.    The default factory just returns Model.query(), sorted by created if it's available.
  45.    """
  46.     Model = controller.meta.Model
  47.     query = Model.query()
  48.     if 'created' in Model._properties and Model._properties['created']._indexed:
  49.         query = query.order(-Model.created)
  50.     return query
  51.  
  52.  
  53. def default_create_factory(controller):
  54.     """
  55.    The default create factory just calls Model()
  56.    """
  57.     return controller.meta.Model()
  58.  
  59.  
  60. def delegate_query_factory(controller):
  61.     """
  62.    Calls Model.Meta.query_factory or Model.list or Model.query.
  63.    """
  64.     Model = controller.Meta.Model
  65.     if hasattr(Model.Meta, 'query_factory'):
  66.         return Model.Meta.query_factory(controller)
  67.     if hasattr(Model, 'list'):
  68.         return Model.list(controller)
  69.     return default_query_factory(controller)
  70.  
  71.  
  72. def delegate_create_factory(controller):
  73.     """
  74.    Calls Model.Meta.create_factory or Model.create or the Model constructor.
  75.    """
  76.     Model = controller.Meta.Model
  77.     if hasattr(Model.Meta, 'create_factory'):
  78.         return Model.Meta.create_factory(controller)
  79.     if hasattr(Model, 'create'):
  80.         return Model.create(controller)
  81.     return default_create_factory(controller)
  82.  
  83.  
  84. # Utility Functions
  85.  
  86.  
  87. def _load_model(controller):
  88.     import_form_base = '.'.join(controller.__module__.split('.')[:-2])
  89.     # Attempt to import the model automatically
  90.     model_name = inflector.singularize(controller.__class__.__name__)
  91.     try:
  92.         module = __import__('%s.models.%s' % (import_form_base, inflector.underscore(model_name)), fromlist=['*'])
  93.         setattr(controller.Meta, 'Model', getattr(module, model_name))
  94.     except (ImportError, AttributeError):
  95.         raise RuntimeError("Scaffold coudn't automatically determine a model class for controller %s, please assign it a Meta.Model class variable." % controller.__class__.__name__)
  96.  
  97.  
  98. def _flash(controller, *args, **kwargs):
  99.     if 'flash_messages' in controller.components and controller.scaffold.flash_messages:
  100.         controller.components.flash_messages(*args, **kwargs)
  101.  
  102.  
  103. # controller Methods
  104.  
  105. [docs]def list(controller): controller.context.set(**{ controller.scaffold.plural: controller.scaffold.query_factory(controller) })
  106.  
  107. [docs]def view(controller, key): item = controller.util.decode_key(key).get() if not item: return 404 controller.context.set(**{ controller.scaffold.singular: item})
  108.  
  109. def save_callback(controller, item, parser):
  110.     parser.update(item)
  111.  
  112.     controller.events.scaffold_before_save(controller=controller, container=parser.container, item=item)
  113.     item.put()
  114.     controller.events.scaffold_after_save(controller=controller, container=parser.container, item=item)
  115.  
  116.  
  117. def parser_action(controller, item, callback=save_callback):
  118.     controller.events.scaffold_before_parse(controller=controller)
  119.     parser = controller.parse_request(fallback=item)
  120.  
  121.     if controller.request.method in ('PUT', 'POST', 'PATCH'):
  122.         if parser.validate():
  123.  
  124.             controller.events.scaffold_before_apply(controller=controller, container=parser.container, item=item)
  125.             callback(controller, item, parser)
  126.             controller.events.scaffold_after_apply(controller=controller, container=parser.container, item=item)
  127.  
  128.             controller.context.set(**{
  129.                 controller.scaffold.singular: item})
  130.  
  131.             _flash(controller, 'The item was saved successfully', 'success')
  132.  
  133.             if controller.scaffold.redirect:
  134.                 return controller.redirect(controller.scaffold.redirect)
  135.  
  136.         else:
  137.             controller.context['errors'] = parser.errors
  138.             _flash(controller, 'There were errors on the form, please correct and try again.', 'error')
  139.  
  140.     controller.context.set(**{
  141.         'form': parser.container,
  142.         controller.scaffold.singular: item})
  143.  
  144.  
  145. [docs]def add(controller): item = controller.scaffold.create_factory(controller) return parser_action(controller, item)
  146.  
  147. [docs]def edit(controller, key): item = controller.util.decode_key(key).get() if not item: return 404 return parser_action(controller, item)
  148.  
  149. [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