class Test(Base): __tablename__ = 'test15' id = sqla.Column('id', sqla.Integer, primary_key=True) data = sqla.Column(ptah.JsonListType())
class Node(Base): """ Base class for persistent objects. .. attribute:: __uri__ Unique object id. **Required** .. attribute:: __type__ Type information object :py:class:`ptah.cms.TypeInformation` .. attribute:: __parent__ Parent of node. Ptah doesn't load `__parent__` automatically. To load node parents use :py:func:`ptah.cms.load_parents` function. .. attribute:: __owner__ URI of owner principal. It possible to load principal object by using :py:func:`ptah.resolve` function. .. attribute:: __local_roles__ :py:class:`ptah.JsonDictType` which contains a principal uri as a key and a sequence of role's granted to principal for Node. .. attribute:: __acls__ a :py:class:`ptah.JsonListType` of :py:class:`ptah.ACL` strings registered with security machinery. .. attribute:: __uri_factory__ function which will return value for __uri__. the uri must be resolvable by using :py:func:`ptah.resolve` function. """ __tablename__ = 'ptah_nodes' __id__ = sqla.Column('id', sqla.Integer, primary_key=True) __type_id__ = sqla.Column('type', sqla.String, info={'uri': True}) __type__ = None __uri__ = sqla.Column('uri', sqla.String, unique=True, nullable=False, info={'uri': True}) __parent_uri__ = sqla.Column('parent', sqla.String, sqla.ForeignKey(__uri__), info={'uri': True}) __owner__ = sqla.Column('owner', sqla.String, default=text_type(''), info={'uri': True}) __local_roles__ = sqla.Column('roles', ptah.JsonDictType(), default={}) __acls__ = sqla.Column('acls', ptah.JsonListType(), default=[]) __children__ = sqla.orm.relationship('Node', backref=sqla.orm.backref( '__parent_ref__', remote_side=[__uri__])) __mapper_args__ = {'polymorphic_on': __type_id__} __parent__ = None __uri_factory__ = None __acl__ = ptah.ACLsProperty() def __init__(self, **kw): self.__owners__ = [] self.__local_roles__ = {} self.__permissions__ = [] for attr, value in kw.items(): setattr(self, attr, value) if '__parent__' in kw and kw['__parent__'] is not None: self.__parent_uri__ = kw['__parent__'].__uri__ try: self.__uri__ = self.__uri_factory__() except TypeError: raise TypeError('Subclass of Node has to override __uri_factory__') @action(permission=View) def info(self): info = OrderedDict(( ('__type__', self.__type_id__), ('__content__', False), ('__uri__', self.__uri__), ('__parents__', [p.__uri__ for p in load_parents(self)]), )) return info
class Test2(ptah.get_base()): __tablename__ = 'test5' id = sqla.Column('id', sqla.Integer, primary_key=True) name = sqla.Column(sqla.Unicode()) json = sqla.Column(ptah.JsonListType())
class BaseContent(Node): """ Base class for content objects. A content class should inherit from `Content` to participate in content hierarchy traversal. .. attribute:: __path__ A string used by the :py:class:`ptah.cms.ContentTraverser` which is used for efficient resolution of URL structure to content models. This is internal implementation and manually editing it can break your hierarchy. .. attribute:: __name__ This is the identifier in a container if you are using containment and hierarchies. .. attribute:: title Content title which is editable by end user. .. attribute:: description Content description which is editable by end user. .. attribute:: view A URI which can be resolved with :py:func:`ptah.resolve` function which represents the 'default' view for content. Akin to index.html or default.php in Apache. .. attribute:: created Content creation time which is set by :py:func:`ptah.cms.content.createdHandler` during object creation. :type: :py:class:`datetime.datetime` .. attribute:: modified Content modification time which is set by :py:func:`ptah.cms.content.modifiedHandler` during object modification. :type: :py:class:`datetime.datetime` .. attribute:: effective :type: :py:class:`datetime.datetime` or None .. attribute:: expires :type: :py:class:`datetime.datetime` or None .. attribute:: creators a :py:class:`ptah.JsonListType` which contains sequence of users. Using principal URIs is a good idea. .. attribute:: subjects a :py:class:`ptah.JsonListType` which contains sequence of subjects. Holding a sequence of URIs could resolve to subject objects. Or you can use strings. .. attribute: publisher a Unicode string which should identify the publisher. .. attribute: contributors a :py:class:`ptah.JsonListType` which contains sequence of contributors. You could keep a sequence of principal URIs. """ __tablename__ = 'ptah_content' __id__ = sqla.Column('id', sqla.Integer, sqla.ForeignKey('ptah_nodes.id'), primary_key=True) __path__ = sqla.Column('path', sqla.Unicode, default=text_type('')) __name_id__ = sqla.Column('name', sqla.Unicode(255)) title = sqla.Column(sqla.Unicode, default=text_type('')) description = sqla.Column(sqla.Unicode, default=text_type(''), info={ 'missing': '', 'field_type': 'textarea' }) view = sqla.Column(sqla.Unicode, default=text_type('')) created = sqla.Column(sqla.DateTime) modified = sqla.Column(sqla.DateTime) effective = sqla.Column(sqla.DateTime) expires = sqla.Column(sqla.DateTime) creators = sqla.Column(ptah.JsonListType(), default=[]) subjects = sqla.Column(ptah.JsonListType(), default=[]) publisher = sqla.Column(sqla.Unicode, default=text_type('')) contributors = sqla.Column(ptah.JsonListType(), default=[]) # sql queries _sql_get = ptah.QueryFreezer(lambda: Session.query(BaseContent).filter( BaseContent.__uri__ == sqla.sql.bindparam('uri'))) _sql_get_in_parent = ptah.QueryFreezer( lambda: Session.query(BaseContent).filter( BaseContent.__name_id__ == sqla.sql.bindparam('key')).filter( BaseContent.__parent_uri__ == sqla.sql.bindparam('parent'))) _sql_parent = ptah.QueryFreezer(lambda: Session.query(BaseContent).filter( BaseContent.__uri__ == sqla.sql.bindparam('parent'))) def __init__(self, **kw): super(BaseContent, self).__init__(**kw) if self.__name__ and self.__parent__ is not None: self.__path__ = '%s%s/' % (self.__parent__.__path__, self.__name__) @hybrid_property def __name__(self): return self.__name_id__ @__name__.setter def __name__(self, value): self.__name_id__ = value def __resource_url__(self, request, info): return '%s%s' % (request.root.__root_path__, self.__path__[len(request.root.__path__):]) @action(permission=DeleteContent) def delete(self): parent = self.__parent__ if parent is None: parent = self.__parent_ref__ if parent is None: raise Error("Can't find parent") del parent[self] @action(permission=ModifyContent) def update(self, **data): if self.__type__: tinfo = self.__type__ for field in tinfo.fieldset.fields(): val = data.get(field.name, field.default) if val is not ptah.form.null: setattr(self, field.name, val) get_current_registry().notify( ptah.events.ContentModifiedEvent(self)) def _extra_info(self, info): if self.__type__: fieldset = self.__type__.fieldset.bind() for field in fieldset.fields(): val = getattr(self, field.name, field.default) info[field.name] = field.serialize(val) info['view'] = self.view info['created'] = self.created info['modified'] = self.modified info['effective'] = self.effective info['expires'] = self.expires def info(self): info = super(BaseContent, self).info() info['__name__'] = self.__name__ info['__content__'] = True info['__container__'] = False self._extra_info(info) return info