diff --git a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/database.py b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/database.py index cf6877d..aba1e49 100644 --- a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/database.py +++ b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/database.py @@ -1,10 +1,42 @@ # -*- coding: utf-8 -*- '''Database module, including the SQLAlchemy database object and DB-related -mixins. +utilities. ''' +from sqlalchemy.orm import relationship +from sqlalchemy.ext.declarative import declared_attr + from .extensions import db +# Helpers from Mike Bayer's atmcraft example app +# https://bitbucket.org/zzzeek/pycon2014_atmcraft/src/a6d96575bc49?at=master +def many_to_one(clsname, **kw): + """Use an event to build a many-to-one relationship on a class. + + This makes use of the :meth:`.References._reference_table` method + to generate a full foreign key relationship to the remote table. + + """ + @declared_attr + def m2o(cls): + cls._references((cls.__name__, clsname)) + return relationship(clsname, **kw) + return m2o + +def one_to_many(clsname, **kw): + """Use an event to build a one-to-many relationship on a class. + + This makes use of the :meth:`.References._reference_table` method + to generate a full foreign key relationship from the remote table. + + """ + @declared_attr + def o2m(cls): + cls._references((clsname, cls.__name__)) + return relationship(clsname, **kw) + return o2m + + class CRUDMixin(object): """Mixin that adds convenience methods for CRUD (create, read, update, delete) operations.