CRUD form overhaul..etc.
This commit is contained in:
parent
dbd99303c4
commit
5b5b0c8738
14 changed files with 207 additions and 218 deletions
|
@ -36,8 +36,11 @@ from webhelpers.html.tags import literal
|
||||||
import formalchemy
|
import formalchemy
|
||||||
from formalchemy.validators import accepts_none
|
from formalchemy.validators import accepts_none
|
||||||
|
|
||||||
|
import edbob
|
||||||
from edbob.lib import pretty
|
from edbob.lib import pretty
|
||||||
|
from edbob.pyramid import Session
|
||||||
from edbob.time import localize
|
from edbob.time import localize
|
||||||
|
from edbob.util import requires_impl
|
||||||
|
|
||||||
from edbob.pyramid.forms.formalchemy.fieldset import *
|
from edbob.pyramid.forms.formalchemy.fieldset import *
|
||||||
from edbob.pyramid.forms.formalchemy.fields import *
|
from edbob.pyramid.forms.formalchemy.fields import *
|
||||||
|
@ -65,6 +68,50 @@ engine = TemplateEngine()
|
||||||
formalchemy.config.engine = engine
|
formalchemy.config.engine = engine
|
||||||
|
|
||||||
|
|
||||||
|
class AlchemyForm(edbob.Object):
|
||||||
|
"""
|
||||||
|
Form to contain a :class:`formalchemy.FieldSet` instance.
|
||||||
|
"""
|
||||||
|
|
||||||
|
create_label = "Create"
|
||||||
|
update_label = "Update"
|
||||||
|
|
||||||
|
allow_successive_creates = False
|
||||||
|
|
||||||
|
def __init__(self, request, fieldset, **kwargs):
|
||||||
|
edbob.Object.__init__(self, **kwargs)
|
||||||
|
self.request = request
|
||||||
|
self.fieldset = fieldset
|
||||||
|
|
||||||
|
def _get_readonly(self):
|
||||||
|
return self.fieldset.readonly
|
||||||
|
|
||||||
|
def _set_readonly(self, val):
|
||||||
|
self.fieldset.readonly = val
|
||||||
|
|
||||||
|
readonly = property(_get_readonly, _set_readonly)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def successive_create_label(self):
|
||||||
|
return "%s and continue" % self.create_label
|
||||||
|
|
||||||
|
def render(self, **kwargs):
|
||||||
|
kwargs['form'] = self
|
||||||
|
if self.readonly:
|
||||||
|
template = '/forms/form_readonly.mako'
|
||||||
|
else:
|
||||||
|
template = '/forms/form.mako'
|
||||||
|
return render(template, kwargs)
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
self.fieldset.sync()
|
||||||
|
Session.flush()
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
self.fieldset.rebind(data=self.request.params)
|
||||||
|
return self.fieldset.validate()
|
||||||
|
|
||||||
|
|
||||||
class ChildGridField(formalchemy.Field):
|
class ChildGridField(formalchemy.Field):
|
||||||
"""
|
"""
|
||||||
Convenience class for including a child grid within a fieldset as a
|
Convenience class for including a child grid within a fieldset as a
|
||||||
|
|
|
@ -35,7 +35,7 @@ __all__ = ['AutocompleteFieldRenderer', 'EnumFieldRenderer',
|
||||||
'YesNoFieldRenderer']
|
'YesNoFieldRenderer']
|
||||||
|
|
||||||
|
|
||||||
def AutocompleteFieldRenderer(service_url, width='300px'):
|
def AutocompleteFieldRenderer(service_url, field_value=None, field_display=None, width='300px'):
|
||||||
"""
|
"""
|
||||||
Autocomplete renderer.
|
Autocomplete renderer.
|
||||||
"""
|
"""
|
||||||
|
@ -46,10 +46,14 @@ def AutocompleteFieldRenderer(service_url, width='300px'):
|
||||||
def focus_name(self):
|
def focus_name(self):
|
||||||
return self.name + '-textbox'
|
return self.name + '-textbox'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def needs_focus(self):
|
||||||
|
return not bool(self.value or field_value)
|
||||||
|
|
||||||
def render(self, **kwargs):
|
def render(self, **kwargs):
|
||||||
kwargs.setdefault('field_name', self.name)
|
kwargs.setdefault('field_name', self.name)
|
||||||
kwargs.setdefault('field_value', self.value)
|
kwargs.setdefault('field_value', self.value or field_value)
|
||||||
kwargs.setdefault('field_display', self.raw_value)
|
kwargs.setdefault('field_display', self.raw_value or field_display)
|
||||||
kwargs.setdefault('service_url', service_url)
|
kwargs.setdefault('service_url', service_url)
|
||||||
kwargs.setdefault('width', width)
|
kwargs.setdefault('width', width)
|
||||||
return render('/forms/field_autocomplete.mako', kwargs)
|
return render('/forms/field_autocomplete.mako', kwargs)
|
||||||
|
|
|
@ -52,10 +52,17 @@ class AlchemyGrid(Grid):
|
||||||
self._formalchemy_grid = formalchemy.Grid(
|
self._formalchemy_grid = formalchemy.Grid(
|
||||||
cls, instances, session=Session(), request=request)
|
cls, instances, session=Session(), request=request)
|
||||||
self._formalchemy_grid.prettify = prettify
|
self._formalchemy_grid.prettify = prettify
|
||||||
|
self.noclick_fields = []
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
return getattr(self._formalchemy_grid, attr)
|
return getattr(self._formalchemy_grid, attr)
|
||||||
|
|
||||||
|
def cell_class(self, field):
|
||||||
|
classes = [field.name]
|
||||||
|
if field.name in self.noclick_fields:
|
||||||
|
classes.append('noclick')
|
||||||
|
return ' '.join(classes)
|
||||||
|
|
||||||
def checkbox(self, row):
|
def checkbox(self, row):
|
||||||
return tags.checkbox('check-'+row.uuid)
|
return tags.checkbox('check-'+row.uuid)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
* Form Wrapper
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
div.form-wrapper {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
* Context Menu
|
* Context Menu
|
||||||
******************************/
|
******************************/
|
||||||
|
@ -19,7 +28,6 @@ div.form,
|
||||||
div.fieldset-form,
|
div.fieldset-form,
|
||||||
div.fieldset {
|
div.fieldset {
|
||||||
float: left;
|
float: left;
|
||||||
margin-left: 50px;
|
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ div.grid table tbody td.delete {
|
||||||
background-position: center;
|
background-position: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
min-width: 18px;
|
min-width: 18px;
|
||||||
|
width: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.grid table tbody tr.hovering {
|
div.grid table tbody tr.hovering {
|
||||||
|
@ -121,6 +122,10 @@ div.grid table.checkable tbody tr {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.grid.clickable table tbody tr td.noclick {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
/* div.grid table.selectable tbody tr.selected, */
|
/* div.grid table.selectable tbody tr.selected, */
|
||||||
/* div.grid table.checkable tbody tr.selected { */
|
/* div.grid table.checkable tbody tr.selected { */
|
||||||
/* background-color: #666666; */
|
/* background-color: #666666; */
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
<%inherit file="/base.mako" />
|
<%inherit file="/form.mako" />
|
||||||
|
|
||||||
<%def name="title()">${(fieldset.crud_title+' : '+fieldset.get_display_text() if fieldset.edit else 'New '+fieldset.crud_title) if crud else ''|n}</%def>
|
<%def name="title()">${"New "+form.pretty_name if form.creating else form.pretty_name+' : '+str(form.fieldset.model)}</%def>
|
||||||
|
|
||||||
<%def name="context_menu_items()"></%def>
|
${parent.body()}
|
||||||
|
|
||||||
<div class="form-wrapper">
|
|
||||||
|
|
||||||
<ul class="context-menu">
|
|
||||||
${self.context_menu_items()}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
${fieldset.render()|n}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
<%inherit file="/base.mako" />
|
<%inherit file="/base.mako" />
|
||||||
|
|
||||||
<%def name="buttons()"></%def>
|
<%def name="context_menu_items()"></%def>
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="form-wrapper">
|
||||||
|
|
||||||
<div class="right">
|
<ul class="context-menu">
|
||||||
${self.menu()}
|
${self.context_menu_items()}
|
||||||
</div>
|
</ul>
|
||||||
|
|
||||||
<div class="left">
|
${form.render()|n}
|
||||||
<% print 'type (2) is', type(form) %>
|
|
||||||
${form.render(buttons=self.buttons)|n}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
<%inherit file="/edbob/form.mako" />
|
<%inherit file="/edbob/form.mako" />
|
||||||
|
|
||||||
${parent.body()}
|
${parent.body()}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
<% _focus_rendered = False %>
|
<% _focus_rendered = False %>
|
||||||
|
|
||||||
<div class="fieldset-form ${class_}">
|
|
||||||
${h.form(fieldset.action_url+('?uuid='+fieldset.model.uuid) if fieldset.edit else '', enctype='multipart/form-data')}
|
|
||||||
|
|
||||||
% for error in fieldset.errors.get(None, []):
|
% for error in fieldset.errors.get(None, []):
|
||||||
<div class="fieldset-error">${error}</div>
|
<div class="fieldset-error">${error}</div>
|
||||||
% endfor
|
% endfor
|
||||||
|
@ -24,7 +21,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
% if not _focus_rendered and (fieldset.focus == field or fieldset.focus is True):
|
% if not _focus_rendered and (fieldset.focus == field or fieldset.focus is True):
|
||||||
% if not field.is_readonly():
|
% if not field.is_readonly() and getattr(field.renderer, 'needs_focus', True):
|
||||||
<script language="javascript" type="text/javascript">
|
<script language="javascript" type="text/javascript">
|
||||||
$(function() {
|
$(function() {
|
||||||
% if hasattr(field.renderer, 'focus_name'):
|
% if hasattr(field.renderer, 'focus_name'):
|
||||||
|
@ -40,25 +37,3 @@
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
% if fieldset.allow_continue:
|
|
||||||
<div class="checkbox">
|
|
||||||
${h.checkbox('add-another', checked=True)}
|
|
||||||
<label for="add-another">Add another after this one</label>
|
|
||||||
</div>
|
|
||||||
% endif
|
|
||||||
|
|
||||||
<div class="buttons">
|
|
||||||
${h.submit('submit', "Save")}
|
|
||||||
<button type="button" class="cancel">Cancel</button>
|
|
||||||
</div>
|
|
||||||
${h.end_form()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script language="javascript" type="text/javascript">
|
|
||||||
$(function() {
|
|
||||||
$('button.cancel').click(function() {
|
|
||||||
location.href = '${fieldset.home_url}';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,62 +1,15 @@
|
||||||
<% _focus_rendered = False %>
|
|
||||||
|
|
||||||
<div class="form">
|
<div class="form">
|
||||||
${h.form(form.action_url, enctype='multipart/form-data')}
|
${h.form(form.action_url, enctype='multipart/form-data')}
|
||||||
|
|
||||||
% for error in form.errors.get(None, []):
|
${form.fieldset.render()|n}
|
||||||
<div class="fieldset-error">${error}</div>
|
|
||||||
% endfor
|
|
||||||
|
|
||||||
% for field in form.render_fields.itervalues():
|
|
||||||
|
|
||||||
<div class="field-couple ${field.name}">
|
|
||||||
% for error in field.errors:
|
|
||||||
<div class="field-error">${error}</div>
|
|
||||||
% endfor
|
|
||||||
${field.label_tag()|n}
|
|
||||||
<div class="field">
|
|
||||||
${field.render()|n}
|
|
||||||
</div>
|
|
||||||
% if 'instructions' in field.metadata:
|
|
||||||
<span class="instructions">${field.metadata['instructions']}</span>
|
|
||||||
% endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
% if (form.focus == field or form.focus is True) and not _focus_rendered:
|
|
||||||
% if not field.is_readonly():
|
|
||||||
<script language="javascript" type="text/javascript">
|
|
||||||
$(function() {
|
|
||||||
$('#${field.renderer.name}').focus();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<% _focus_rendered = True %>
|
|
||||||
% endif
|
|
||||||
% endif
|
|
||||||
|
|
||||||
% endfor
|
|
||||||
|
|
||||||
% if form.successive:
|
|
||||||
<div class="checkbox">
|
|
||||||
${h.checkbox('keep-going', checked=True)}
|
|
||||||
<label for="keep-going">Add another after this one</label>
|
|
||||||
</div>
|
|
||||||
% endif
|
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
% if buttons:
|
${h.submit('create', form.create_label if form.creating else form.update_label)}
|
||||||
${capture(buttons)}
|
% if form.creating and form.allow_successive_creates:
|
||||||
% else:
|
${h.submit('create_and_continue', form.successive_create_label)}
|
||||||
${h.submit('submit', "Save")}
|
|
||||||
<button type="button" class="cancel">Cancel</button>
|
|
||||||
% endif
|
% endif
|
||||||
</div>
|
<button type="button" onclick="location.href = '${form.cancel_url}';">Cancel</button>
|
||||||
${h.end_form()}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script language="javascript" type="text/javascript">
|
${h.end_form()}
|
||||||
$(function() {
|
</div>
|
||||||
$('button.cancel').click(function() {
|
|
||||||
location.href = '${form.home_url}';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
3
edbob/pyramid/templates/forms/form_readonly.mako
Normal file
3
edbob/pyramid/templates/forms/form_readonly.mako
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<div class="form">
|
||||||
|
${form.fieldset.render()|n}
|
||||||
|
</div>
|
|
@ -23,7 +23,7 @@
|
||||||
<td class="checkbox">${grid.checkbox(row)}</td>
|
<td class="checkbox">${grid.checkbox(row)}</td>
|
||||||
% endif
|
% endif
|
||||||
% for field in grid.iter_fields():
|
% for field in grid.iter_fields():
|
||||||
<td class="${field.name}">${grid.render_field(field)}</td>
|
<td class="${grid.cell_class(field)}">${grid.render_field(field)}</td>
|
||||||
% endfor
|
% endfor
|
||||||
% for col in grid.extra_columns:
|
% for col in grid.extra_columns:
|
||||||
<td class="noclick ${col.name}">${col.callback(row)}</td>
|
<td class="noclick ${col.name}">${col.callback(row)}</td>
|
||||||
|
|
|
@ -33,9 +33,10 @@ from webhelpers.html import literal
|
||||||
from webhelpers.html.tags import link_to
|
from webhelpers.html.tags import link_to
|
||||||
|
|
||||||
from edbob.pyramid.views.core import *
|
from edbob.pyramid.views.core import *
|
||||||
from edbob.pyramid.views.autocomplete import *
|
|
||||||
from edbob.pyramid.views.form import *
|
|
||||||
from edbob.pyramid.views.grids import *
|
from edbob.pyramid.views.grids import *
|
||||||
|
from edbob.pyramid.views.crud import *
|
||||||
|
from edbob.pyramid.views.autocomplete import *
|
||||||
|
# from edbob.pyramid.views.form import *
|
||||||
|
|
||||||
|
|
||||||
def forbidden(request):
|
def forbidden(request):
|
||||||
|
|
|
@ -28,22 +28,20 @@
|
||||||
|
|
||||||
from pyramid.httpexceptions import HTTPFound
|
from pyramid.httpexceptions import HTTPFound
|
||||||
|
|
||||||
|
import formalchemy
|
||||||
|
|
||||||
from edbob.pyramid import Session
|
from edbob.pyramid import Session
|
||||||
from edbob.pyramid.forms.formalchemy.fieldset import FieldSet
|
from edbob.pyramid.forms.formalchemy import AlchemyForm
|
||||||
|
from edbob.pyramid.views.core import View
|
||||||
from edbob.util import requires_impl
|
from edbob.util import requires_impl
|
||||||
|
|
||||||
|
|
||||||
class Crud(object):
|
__all__ = ['CrudView']
|
||||||
|
|
||||||
routes = ['create', 'read', 'update', 'delete']
|
|
||||||
|
|
||||||
route_prefix = None
|
class CrudView(View):
|
||||||
url_prefix = None
|
|
||||||
template_prefix = None
|
|
||||||
permission_prefix = None
|
|
||||||
|
|
||||||
def __init__(self, request):
|
allow_successive_creates = False
|
||||||
self.request = request
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@requires_impl(is_property=True)
|
@requires_impl(is_property=True)
|
||||||
|
@ -51,7 +49,7 @@ class Crud(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def crud_title(self):
|
def pretty_name(self):
|
||||||
return self.mapped_class.__name__
|
return self.mapped_class.__name__
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -65,64 +63,96 @@ class Crud(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cancel_route(self):
|
def cancel_route(self):
|
||||||
return None
|
return self.home_route
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cancel_url(self):
|
||||||
|
return self.request.route_url(self.cancel_route)
|
||||||
|
|
||||||
def make_fieldset(self, model, **kwargs):
|
def make_fieldset(self, model, **kwargs):
|
||||||
if 'action_url' not in kwargs:
|
|
||||||
kwargs['action_url'] = self.request.current_route_url()
|
|
||||||
if 'home_url' not in kwargs:
|
|
||||||
kwargs['home_url'] = self.home_url
|
|
||||||
|
|
||||||
kwargs.setdefault('session', Session())
|
kwargs.setdefault('session', Session())
|
||||||
fs = FieldSet(model, **kwargs)
|
fieldset = formalchemy.FieldSet(model, **kwargs)
|
||||||
fs.create = model is self.mapped_class
|
return fieldset
|
||||||
fs.update = not fs.create
|
|
||||||
return fs
|
|
||||||
|
|
||||||
def fieldset(self, obj):
|
def fieldset(self, model):
|
||||||
return self.make_fieldset(obj)
|
return self.make_fieldset(model)
|
||||||
|
|
||||||
def post_sync(self, fs):
|
def make_form(self, model, **kwargs):
|
||||||
pass
|
self.creating = model is self.mapped_class
|
||||||
|
self.updating = not self.creating
|
||||||
|
|
||||||
def validation_failed(self, fs):
|
fieldset = self.fieldset(model)
|
||||||
pass
|
kwargs.setdefault('pretty_name', self.pretty_name)
|
||||||
|
kwargs.setdefault('action_url', self.request.current_route_url())
|
||||||
|
kwargs.setdefault('cancel_url', self.cancel_url)
|
||||||
|
kwargs.setdefault('creating', self.creating)
|
||||||
|
kwargs.setdefault('updating', self.updating)
|
||||||
|
form = AlchemyForm(self.request, fieldset, **kwargs)
|
||||||
|
|
||||||
|
if form.creating:
|
||||||
|
if hasattr(self, 'create_label'):
|
||||||
|
form.create_label = self.create_label
|
||||||
|
if self.allow_successive_creates:
|
||||||
|
form.allow_successive_creates = True
|
||||||
|
if hasattr(self, 'successive_create_label'):
|
||||||
|
form.successive_create_label = self.successive_create_label
|
||||||
|
|
||||||
|
return form
|
||||||
|
|
||||||
|
def form(self, model):
|
||||||
|
return self.make_form(model)
|
||||||
|
|
||||||
def crud(self, model, readonly=False):
|
def crud(self, model, readonly=False):
|
||||||
|
|
||||||
fs = self.fieldset(model)
|
form = self.form(model)
|
||||||
if readonly:
|
if readonly:
|
||||||
fs.readonly = True
|
form.readonly = True
|
||||||
if not fs.readonly and self.request.POST:
|
|
||||||
fs.rebind(data=self.request.params)
|
|
||||||
if fs.validate():
|
|
||||||
|
|
||||||
fs.sync()
|
if not form.readonly and self.request.POST:
|
||||||
Session.add(fs.model)
|
if form.validate():
|
||||||
Session.flush()
|
form.save()
|
||||||
|
|
||||||
result = self.post_sync(fs)
|
result = self.post_save(form)
|
||||||
if result:
|
if result:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# Session.add(fs.model)
|
if form.creating:
|
||||||
# Session.flush()
|
self.flash_create(form.fieldset.model)
|
||||||
if fs.create:
|
|
||||||
self.flash_create(fs.model)
|
|
||||||
else:
|
else:
|
||||||
self.flash_update(fs.model)
|
self.flash_update(form.fieldset.model)
|
||||||
|
|
||||||
if self.request.params.get('add-another') == '1':
|
if (form.creating and form.allow_successive_creates
|
||||||
|
and self.request.params.get('create_and_continue')):
|
||||||
return HTTPFound(location=self.request.current_route_url())
|
return HTTPFound(location=self.request.current_route_url())
|
||||||
|
|
||||||
return HTTPFound(location=self.home_url)
|
return HTTPFound(location=self.home_url)
|
||||||
|
|
||||||
self.validation_failed(fs)
|
self.validation_failed(form)
|
||||||
|
|
||||||
if not fs.edit:
|
kwargs = self.template_kwargs(form)
|
||||||
fs.allow_continue = True
|
kwargs['form'] = form
|
||||||
|
return kwargs
|
||||||
|
|
||||||
return {'fieldset': fs, 'crud': True}
|
def template_kwargs(self, form):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def post_save(self, form):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validation_failed(self, form):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def flash_create(self, model):
|
||||||
|
self.request.session.flash("%s \"%s\" has been created." %
|
||||||
|
(self.pretty_name, model))
|
||||||
|
|
||||||
|
def flash_delete(self, model):
|
||||||
|
self.request.session.flash("%s \"%s\" has been deleted." %
|
||||||
|
(self.pretty_name, model))
|
||||||
|
|
||||||
|
def flash_update(self, model):
|
||||||
|
self.request.session.flash("%s \"%s\" has been updated." %
|
||||||
|
(self.pretty_name, model))
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
return self.crud(self.mapped_class)
|
return self.crud(self.mapped_class)
|
||||||
|
@ -139,6 +169,9 @@ class Crud(object):
|
||||||
assert model
|
assert model
|
||||||
return self.crud(model)
|
return self.crud(model)
|
||||||
|
|
||||||
|
def pre_delete(self, model):
|
||||||
|
pass
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
uuid = self.request.matchdict['uuid']
|
uuid = self.request.matchdict['uuid']
|
||||||
model = Session.query(self.mapped_class).get(uuid) if uuid else None
|
model = Session.query(self.mapped_class).get(uuid) if uuid else None
|
||||||
|
@ -150,38 +183,3 @@ class Crud(object):
|
||||||
Session.flush() # Don't set flash message if delete fails.
|
Session.flush() # Don't set flash message if delete fails.
|
||||||
self.flash_delete(model)
|
self.flash_delete(model)
|
||||||
return HTTPFound(location=self.home_url)
|
return HTTPFound(location=self.home_url)
|
||||||
|
|
||||||
def flash_create(self, model):
|
|
||||||
self.request.session.flash("%s \"%s\" has been created." %
|
|
||||||
(self.crud_title, model))
|
|
||||||
|
|
||||||
def flash_delete(self, model):
|
|
||||||
self.request.session.flash("%s \"%s\" has been deleted." %
|
|
||||||
(self.crud_title, model))
|
|
||||||
|
|
||||||
def flash_update(self, model):
|
|
||||||
self.request.session.flash("%s \"%s\" has been updated." %
|
|
||||||
(self.crud_title, model))
|
|
||||||
|
|
||||||
def pre_delete(self, model):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def add_routes(cls, config):
|
|
||||||
route_name_prefix = cls.route_prefix or cls.mapped_class.__name__.lower()
|
|
||||||
route_url_prefix = cls.url_prefix or '/%ss' % route_name_prefix
|
|
||||||
renderer_prefix = cls.template_prefix or route_url_prefix
|
|
||||||
permission_prefix = cls.permission_prefix or '%ss' % route_name_prefix
|
|
||||||
|
|
||||||
for route in cls.routes:
|
|
||||||
kw = dict(
|
|
||||||
attr=route,
|
|
||||||
route_name='%s.%s' % (route_name_prefix, route),
|
|
||||||
renderer='%s/%s.mako' % (renderer_prefix, route),
|
|
||||||
permission='%s.%s' % (permission_prefix, route),
|
|
||||||
)
|
|
||||||
if route == 'create':
|
|
||||||
config.add_route(kw['route_name'], '%s/new' % route_url_prefix)
|
|
||||||
else:
|
|
||||||
config.add_route(kw['route_name'], '%s/{uuid}/%s' % (route_url_prefix, route))
|
|
||||||
config.add_view(cls, http_cache=0, **kw)
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue