4 ms·
I prefer keeping routes in a separate file. Instead of @app.route('/') def index(): pass I keep a routes array routes = [ ('/',
by irahul 14y ago
I prefer keeping routes in a separate file.
Instead of
@app.route('/')
def index():
pass
I keep a routes array
routes = [
('/', endpoint='index', view_func=index)
...
]
I find it a lot pleasant to look up all routes at the same place rather than guessing or searching. Also, I give an explicit name to all endpoints.
I do the same with blueprints. Blueprints have their own urls.py, and blueprints don't specify the url prefix. For eg, a comment blueprint will define '/', rather than '/comments'. I leave the url prefix to the main application.
app.register_blueprint(comment, url_prefix='/comment')
For migrations, I prefer alembic to sql migrations - https://alembic.readthedocs.org/en/latest/tutorial.html https://alembic.readthedocs.org/en/latest/tutorial.html I find Alembic simpler than SQLAlchemy(without compromising on power). Alembic can autogenerate migrations based on your model definitions. The way I work is I add a new model, and then run alembic to autogenerate the migration. Same goes for altering models.
For settings, I maintain setting.py, dev_settings.py, prod_settings.py. settings.py contains all the common settings. If environment is not defined, I do a `from dev_settings import *`, else I do a relevant import for the environment.
I also prefer having BEFORE_REQUESTS, AFTER_REQUESTS, MIDDLEWARES, LOG_HANDLERS, TEMPLATE_FILTERS, CONTEXT_PROCESSORS, ERROR_HANDLERS... in settings, and in main.py, call the relevant functions. That way, I don't have to hunt down the codebase. For blueprints, I define the same variables in __init__.py.
Model forms are another time saver(use wtforms, or preferably flask-wtform)
from flask.ext.wtf import Form
from wtforms.ext.sqlalchemy.orm import model_form
import models
PostForm = model_form(models.Post, models.db.session, Form, field_args = {
'name': {'validators': []},
'title': {'validators': []},
'content': {'validators': []},
})
models.Post is flask-sqlalchemy model, models.db.session is sqlalcheymy session. You don't need to list all model fields for your model form. I find keeping models and forms in sync a pain. This way, I only keep the validations in sync(field_args isn't required - that's an example of adding validations).
I use flask-debugtoolbar for basic profiling and debugging. flask-webassets is awesome for managing assets and dynamic compilation. flask-script for writing manage.py jobs(python manage.py get_deps, python manage.py db_createall etc etc)
- lifeisstillgood 14y agoOn the routes side it also means you don't fact around having to import a module to get your app - if you can instantiate the app (as it were) and then set up routes you can create a factory much more easily and pass it around with little worries - but anchored to a module import as in the docs is less than helpful Would love to see or hear more about your default setups though. Is there an example in OSS?
- ceol 14y agoThat's a great point. I think I will start using that method for defining routes, myself.
- irahul 14y agoI don't have something clean, but I pushed a demo https://github.com/rahulkmr/flask-bigapp-template https://github.com/rahulkmr/flask-bigapp-template The focus points are: 1. Routes in a separate file. Check config/urls.py 2. Blueprints are level of abstraction. Check blueprints/post. It's a simple blogging app. Blueprints have their own forms, models, urls, views. 3. Add blueprints to the app under config/blueprints.py You can mount the blueprint at '/' or an url prefix viz '/posts' 4. Blueprints define their own hooks. Check blueprints/post/__init__.py for an example. 5. Schema migration using alembic. Write your model: class Post(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80)) title = db.Column(db.String(200)) content = db.Column(db.Text) def __init__(self, name, title, content): self.name = name self.title = title self.content = content Save your file and add the blueprint to config/blueprints.py(if it's a blueprint), and run: alembic revision --autogenerate -m "Create post table." Check the generated schema in migrate/versions/ Tweak the migration and then `alembic upgrade head` 6. Flask-WTF and wtforms in general used for validation. 7. settings.py used for hooks. See config/settings.py and main.py main.py is the glue. The code is quite simple as it doesn't do much. Ignore manage.py. That's my personal scaffold generator(like rails). Also ignore the custom template formats. That again is my personal slimish jinja templates. I use some variation of this template in my projects. This is just guidelines. You can modify it to your heart's content to suit your needs.
- 14y ago