Project/
controllers/
controllers1.py
controllers2.py
model/
models1.py
models2.py
templates/
templates1/
templates2/
routes.py
мы получаем Project/
app1/
models.py
routes.py
views.py
app2/
models.py
routes.py
views.py
templates/
templates1/
templates2/
Разработчики не стали менять архитектуру Pylons и создавать Pylons 2.0, а начали развивать новый проект Pyramid с похожей на Django структурой проекта. При этом Pylons не считается устаревшим, а просто имеет немного другой подход к разработке.
Стоит ли сейчас выбирать Pylons? Да, если вы его хорошо знаете и не планируете создавать слишком масштабное приложение, иначе лучше все таки выбрать Pyramid.
Посмотрим как в нем организовать структуру проекта:
После создания проект выглядит так
MyProject/ ├── CHANGES.txt ├── development.ini ├── MANIFEST.in ├── myproject │ ├── __init__.py │ ├── models.py │ ├── scripts/ │ ├── static/ │ ├── templates/ │ ├── tests.py │ └── views.py ├── production.ini ├── README.txt ├── setup.cfg └── setup.py
Наша задача перенести models.py, views.py, tests.py в app1. Создаем папку app1 и переносим файлы.
Должно получится так:
MyProject/ . ├── CHANGES.txt ├── development.ini ├── MANIFEST.in ├── myproject │ ├── app1 │ │ ├── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ ├── __init__.py │ ├── scripts │ │ ├── initializedb.py │ │ └── __init__.py │ ├── static │ │ ├── favicon.ico │ │ ├── footerbg.png │ │ ├── headerbg.png │ │ ├── ie6.css │ │ ├── middlebg.png │ │ ├── pylons.css │ │ ├── pyramid.png │ │ ├── pyramid-small.png │ │ └── transparent.gif │ └── templates │ └── mytemplate.pt ├── production.ini ├── README.txt ├── setup.cfg └── setup.py
Меняем __init__.py в проекте:
Вместо
from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from .models import DBSession
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
config = Configurator(settings=settings)
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('home', '/')
config.scan()
return config.make_wsgi_app()
Делаем
from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from .models import DBSession
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
config = Configurator(settings=settings)
config.add_static_view('static', 'static', cache_max_age=3600)
# add config for each of your subapps
config.include('myproject.app1')
# pyramid_jinja2 configuration
config.include('pyramid_jinja2')
config.add_jinja2_search_path("myproject:templates")
return config.make_wsgi_app()
Теперь в этом __init__.py мы будем хранить глобальные настройки, а в инитах апликайшинах настройки самих апликайшинов.
Добавляем models.py в основной проект
MyProject/ . ├── CHANGES.txt ├── development.ini ├── MANIFEST.in ├── myproject │ ├── app1 │ │ ├── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ ├── __init__.py │ ├── scripts │ │ ├── initializedb.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ ├── favicon.ico │ │ ├── footerbg.png │ │ ├── headerbg.png │ │ ├── ie6.css │ │ ├── middlebg.png │ │ ├── pylons.css │ │ ├── pyramid.png │ │ ├── pyramid-small.png │ │ └── transparent.gif │ └── templates │ └── mytemplate.pt ├── production.ini ├── README.txt ├── setup.cfg └── setup.py
В нем будет хранится сессия SQLAlchemy общая для всех проектов
from zope.sqlalchemy import ZopeTransactionExtension
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import (
scoped_session,
sessionmaker,
)
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()
Меняем __init__.py в app1
def includeme(config):
config.add_route('home', '/')
config.scan()
Меняем models.py в app1
from sqlalchemy import (
Column,
Integer,
Text,
)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import (
scoped_session,
sessionmaker,
)
from ..models import (
DBSession,
Base,
)
class MyModel(Base):
__tablename__ = 'models'
id = Column(Integer, primary_key=True)
name = Column(Text, unique=True)
value = Column(Integer)
def __init__(self, name, value):
self.name = name
self.value = value
Меняем tests.py
import unittest
import transaction
from pyramid import testing
from ..models import DBSession
class TestMyView(unittest.TestCase):
def setUp(self):
self.config = testing.setUp()
from sqlalchemy import create_engine
engine = create_engine('sqlite://')
from .models import (
Base,
MyModel,
)
DBSession.configure(bind=engine)
Base.metadata.create_all(engine)
with transaction.manager:
model = MyModel(name='one', value=55)
DBSession.add(model)
def tearDown(self):
DBSession.remove()
testing.tearDown()
def test_it(self):
from .views import my_view
request = testing.DummyRequest()
info = my_view(request)
self.assertEqual(info['one'].name, 'one')
self.assertEqual(info['project'], 'MyProject')
Меняем views.py
from sqlalchemy.exc import DBAPIError
from ..models import DBSession
from .models import MyModel
@view_config(route_name='home', renderer='../templates/mytemplate.pt')
def my_view(request):
try:
one = DBSession.query(MyModel).filter(MyModel.name=='one').first()
except DBAPIError:
return Response(conn_err_msg, content_type='text/plain', status_int=500)
return {'one':one, 'project':'MyProject'}
conn_err_msg = """\
Pyramid is having a problem using your SQL database. The problem
might be caused by one of the following things:
1. You may need to run the "initialize_MyProject_db" script
to initialize your database tables. Check your virtual
environment's "bin" directory for this script and try to run it.
2. Your database server may not be running. Check that the
database server referred to by the "sqlalchemy.url" setting in
your "development.ini" file is running.
After you fix the problem, please restart the Pyramid application to
try it again.
"""
Меняем initializedb.py в scripts
import os
import sys
import transaction
from sqlalchemy import engine_from_config
from pyramid.paster import (
get_appsettings,
setup_logging,
)
from ..models import (
DBSession,
Base,
)
from ..app1.models import MyModel
def usage(argv):
cmd = os.path.basename(argv[0])
print('usage: %s \n'
'(example: "%s development.ini")' % (cmd, cmd))
sys.exit(1)
def main(argv=sys.argv):
if len(argv) != 2:
usage(argv)
config_uri = argv[1]
setup_logging(config_uri)
settings = get_appsettings(config_uri)
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
Base.metadata.create_all(engine)
with transaction.manager:
model = MyModel(name='one', value=1)
DBSession.add(model)
Выполняем python setup.py install, запускаем проект, профит!
Остальные апликайшины добавляются по аналогии.
Навеянно этим http://stackoverflow.com/questions/6012991/pyramid-project-structure
со статикой чегонтьбы придумать.
ОтветитьУдалитьв джанге очень удачно сделано.
Может я конечно не все знаю про Джангу но в по моему в Pyramid это делается аналогично config.add_static_view('static', 'static', cache_max_age=3600)
УдалитьЗдесь все описано: http://pyramid.readthedocs.org/en/latest/narr/assets.html
Для деплоя можно отдавать через nginx например.
так, да не так :)
Удалитьили я чтото не доконца осилил.
в джанге в каждом app своя статика.
и она потом радостно склеивается в одну (и простой командой деплоится куда скажешь, в т.ч. симлинками). хотя эта красивость не так давно появилась в полном объеме(чуть ли не в 1.4).
Последнюю джангу которую я использовал это была 0.96 версия поэтому мне сложно представить что за магия используется там сейчас в статике. Если я правильно понял задачу, то вам нужно в pyramid подключить какое то приложение к своему и сделать так что бы статика читалась из подключенного и из вашего проекта.
УдалитьДля подключения проекта можно покурить статью:
http://docs.pylonsproject.org/projects/pyramid/en/1.0-branch/narr/extending.html
Например в includeme подключаемого проекта pyramid_A:
def includeme(config):
....config.include('pyramid_jinja2')
....config.add_static_view('static_A', 'pyramid_A:static')
....config.add_translation_dirs("pyramid_A:locale/")
....config.include(add_routes)
....config.scan()
В вашем проекте pyramid_B:
config.include("pyramid_A")
config.add_jinja2_search_path(("pyramid_B:templates", "pyramid_A:templates"))
config.add_static_view('static_B', 'pyramid_B:static')
Теперь в шаблонах просто пишите путь /static_A/css/blablabla.css или /static_B/img/blablabla.img
В принципе в документации более подробно описан метод подключения нескольких директорий статики: http://pyramid.readthedocs.org/en/latest/narr/assets.html#generating-static-asset-urls
Примерно это. просто хочется немного автомотизировать чтоли и деплой прикрутить
Удалить