% pip install FormAlchemy fa.query GeoFormAlchemy
|
|
% pip install FormAlchemy fa.query GeoFormAlchemy
|
- You have now more templates available:
% paster create --list-templates
basic_package: A basic setuptools-enabled package
geo_fa: Pylons application template with GeoFormAlchemy support
mapfish: MapFish application template
mapfish_client: MapFish client plugin template
paste_deploy: A web application deployed through paste.deploy
pylons: Pylons application template
pylons_fa: Pylons application template with formalchemy support
pylons_minimal: Pylons minimal application template
|
|
% paster create --list-templates
basic_package: A basic setuptools-enabled package
geo_fa: Pylons application template with GeoFormAlchemy support
mapfish: MapFish application template
mapfish_client: MapFish client plugin template
paste_deploy: A web application deployed through paste.deploy
pylons: Pylons application template
pylons_fa: Pylons application template with formalchemy support
pylons_minimal: Pylons minimal application template
|
- You can run the command to add some of the GeoFormAlchemy or the formalchemy support to your project:
% paster create -t geo_fa
|
|
% paster create -t geo_fa
|
Keep the default values except for the first one
Enter admin_controller (Add formalchemy's admin controller) [False]: True
|
|
Enter admin_controller (Add formalchemy's admin controller) [False]: True
|
And answer no unless you want to overrite a file:
Overwrite ./MyApp/myapp/config/environment.py [y/n/d/B/?] n
[etc ...]
|
|
Overwrite ./MyApp/myapp/config/environment.py [y/n/d/B/?] n
[etc ...]
|
- If you do not run the paster create command, you’ll have to add those files directly:
- Add the file
myapp/controllers/admin.py
- Add the file
myapp/forms/__init__.py
- Add the template files in (on githhub-FormAlchemy and github-GeoFormAlchemy)
myapp/templates/forms/ fieldset.mako,
fieldset_readonly.mako, grid.mako, grid_readonly.mako, map.mako, map_js.mako,
restfieldset.mako
- Modify
myapp/config/routing.py
### myapp/controllers/admin.py
import logging
from formalchemy.ext.pylons.controller import ModelsController
from webhelpers.paginate import Page
from myapp.lib.base import BaseController, render
from myapp import model
from myapp import forms
from myapp.model import meta
log = logging.getLogger(__name__)
class AdminControllerBase(BaseController):
model = model # where your SQLAlchemy mappers are
forms = forms # module containing FormAlchemy fieldsets definitions
def Session(self): # Session factory
return meta.Session
## customize the query for a model listing
# def get_page(self):
# if self.model_name == 'Foo':
# return Page(meta.Session.query(model.Foo).order_by(model.Foo.bar)
# return super(AdminControllerBase, self).get_page()
AdminController = ModelsController(AdminControllerBase,
prefix_name='admin',
member_name='model',
collection_name='models',
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
### myapp/controllers/admin.py
import logging
from formalchemy.ext.pylons.controller import ModelsController
from webhelpers.paginate import Page
from myapp.lib.base import BaseController, render
from myapp import model
from myapp import forms
from myapp.model import meta
log = logging.getLogger(__name__)
class AdminControllerBase(BaseController):
model = model # where your SQLAlchemy mappers are
forms = forms # module containing FormAlchemy fieldsets definitions
def Session(self): # Session factory
return meta.Session
## customize the query for a model listing
# def get_page(self):
# if self.model_name == 'Foo':
# return Page(meta.Session.query(model.Foo).order_by(model.Foo.bar)
# return super(AdminControllerBase, self).get_page()
AdminController = ModelsController(AdminControllerBase,
prefix_name='admin',
member_name='model',
collection_name='models',
)
|
- Modify
myapp/config/routing.py
### In myapp/config/routing.py
# Map the /admin url to FA's AdminController
# Map static files
map.connect('fa_static', '/admin/_static/{path_info:.*}', controller='admin', action='static')
# Index page
map.connect('admin', '/admin', controller='admin', action='models')
map.connect('formatted_admin', '/admin.json', controller='admin', action='models', format='json')
# Models
map.resource('model', 'models', path_prefix='/admin/{model_name}', controller='admin')
|
|
### In myapp/config/routing.py
# Map the /admin url to FA's AdminController
# Map static files
map.connect('fa_static', '/admin/_static/{path_info:.*}', controller='admin', action='static')
# Index page
map.connect('admin', '/admin', controller='admin', action='models')
map.connect('formatted_admin', '/admin.json', controller='admin', action='models', format='json')
# Models
map.resource('model', 'models', path_prefix='/admin/{model_name}', controller='admin')
|
### myapp/forms/__init__.py
from pylons import config
from myapp.model import my_app_points
from myapp.lib.base import render
from formalchemy import config as fa_config
from formalchemy import templates
from formalchemy import validators
from formalchemy import fields
from formalchemy import forms
from formalchemy import tables
from formalchemy.ext.fsblob import FileFieldRenderer
from formalchemy.ext.fsblob import ImageFieldRenderer
from geoformalchemy.base import GeometryFieldRenderer
from geoalchemy import geometry
forms.FieldSet.default_renderers[geometry.Geometry] = GeometryFieldRenderer
fa_config.encoding = 'utf-8'
class TemplateEngine(templates.TemplateEngine):
def render(self, name, **kwargs):
return render('/forms/%s.mako' % name, extra_vars=kwargs)
fa_config.engine = TemplateEngine()
class FieldSet(forms.FieldSet):
pass
class Grid(tables.Grid):
pass
## Initialize fieldsets
#Foo = FieldSet(model.Foo)
#Reflected = FieldSet(Reflected)
## Initialize grids
#FooGrid = Grid(model.Foo)
#ReflectedGrid = Grid(Reflected)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
### myapp/forms/__init__.py
from pylons import config
from myapp.model import my_app_points
from myapp.lib.base import render
from formalchemy import config as fa_config
from formalchemy import templates
from formalchemy import validators
from formalchemy import fields
from formalchemy import forms
from formalchemy import tables
from formalchemy.ext.fsblob import FileFieldRenderer
from formalchemy.ext.fsblob import ImageFieldRenderer
from geoformalchemy.base import GeometryFieldRenderer
from geoalchemy import geometry
forms.FieldSet.default_renderers[geometry.Geometry] = GeometryFieldRenderer
fa_config.encoding = 'utf-8'
class TemplateEngine(templates.TemplateEngine):
def render(self, name, **kwargs):
return render('/forms/%s.mako' % name, extra_vars=kwargs)
fa_config.engine = TemplateEngine()
class FieldSet(forms.FieldSet):
pass
class Grid(tables.Grid):
pass
## Initialize fieldsets
#Foo = FieldSet(model.Foo)
#Reflected = FieldSet(Reflected)
## Initialize grids
#FooGrid = Grid(model.Foo)
#ReflectedGrid = Grid(Reflected)
|
Adding a model to the Admin view
One of my models
myapp/model/my_app_points.py
was defined as such
###myapp/model/my_app_points.py
from sqlalchemy import Column, types
from geoalchemy import GeometryColumn, Point
from mapfish.sqlalchemygeom import GeometryTableMixIn
from mapfishapp.model.meta import Session, Base
class MyAppPoint(Base, GeometryTableMixIn):
autoload_with = Session.bind
__tablename__ = 'my_app_point'
__table_args__ = {
"autoload_with": Session.bind,
"autoload": True,
}
way = GeometryColumn(Point(srid=900913))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
###myapp/model/my_app_points.py
from sqlalchemy import Column, types
from geoalchemy import GeometryColumn, Point
from mapfish.sqlalchemygeom import GeometryTableMixIn
from mapfishapp.model.meta import Session, Base
class MyAppPoint(Base, GeometryTableMixIn):
autoload_with = Session.bind
__tablename__ = 'my_app_point'
__table_args__ = {
"autoload_with": Session.bind,
"autoload": True,
}
way = GeometryColumn(Point(srid=900913))
|
I’d get an error by importing that class in
myapp/model/__init__.py
from myapp.models.my_app_points import MyAppPoint
|
|
from myapp.models.my_app_points import MyAppPoint
|
would lead to that error:
sqlalchemy.exc.UnboundExecutionError: No engine is bound to this Table's MetaData.
Pass an engine to the Table via autoload_with=<someengine>, or associate the MetaData
with an engine via metadata.bind=<someengine>
|
|
sqlalchemy.exc.UnboundExecutionError: No engine is bound to this Table's MetaData.
Pass an engine to the Table via autoload_with=<someengine>, or associate the MetaData
with an engine via metadata.bind=<someengine>
|
Modifying myapp/model/__init__.py by adding Base.metadata.bind = engine at the end of init_model(engine) did not work.
The solution I found after checking the formalchemy code was to modify the myapp/controllers/admin.py and pass a list of the model classes to list in the web admin view.
###Modify in myapp/controllers/admin.py
from myapp.model.my_app_points import MyAppPoint
list_models = [MyAppPoint,]
class AdminControllerBase(BaseController):
model = list_models # where your SQLAlchemy mappers are
forms = forms # module containing FormAlchemy fieldsets definitions
|
|
###Modify in myapp/controllers/admin.py
from myapp.model.my_app_points import MyAppPoint
list_models = [MyAppPoint,]
class AdminControllerBase(BaseController):
model = list_models # where your SQLAlchemy mappers are
forms = forms # module containing FormAlchemy fieldsets definitions
|
And finally you can add something like that at the end of your
myapp/forms/__init__.py
MyAppPoint = FieldSet(my_app_points.MyAppPoint)
MyAppPoint.configure(options=[MyAppPoint.way.label('Geometry').required()])
MyAppPoint.way.set(options=[
('map_srid', 900913),
('base_layer', 'new OpenLayers.Layer.OSM("OSM")'),
('openlayers_lib', '/lib/openlayers/lib/OpenLayers.js'),
('zoom', 14)
])
|
|
MyAppPoint = FieldSet(my_app_points.MyAppPoint)
MyAppPoint.configure(options=[MyAppPoint.way.label('Geometry').required()])
MyAppPoint.way.set(options=[
('map_srid', 900913),
('base_layer', 'new OpenLayers.Layer.OSM("OSM")'),
('openlayers_lib', '/lib/openlayers/lib/OpenLayers.js'),
('zoom', 14)
])
|
Sources: mapfish-geoformalchemy,