4.1. Access to persistent data

Python-level access to persistent data is provided by the Entity class.

An entity class is bound to a schema entity type. Descriptors are added when classes are registered in order to initialize the class according to its schema:

  • the attributes defined in the schema appear as attributes of these classes
  • the relations defined in the schema appear as attributes of these classes, but are lists of instances

Formatting and output generation:

  • view(__vid, __registry='views', **kwargs)(), applies the given view to the entity (and returns a unicode string)
  • absolute_url(*args, **kwargs)(), returns an absolute URL including the base-url
  • rest_path(), returns a relative REST URL to get the entity
  • printable_value(attr, value=_marker, attrtype=None, format='text/html', displaytime=True)(), returns a string enabling the display of an attribute value in a given format (the value is automatically recovered if necessary)

Data handling:

  • as_rset(), converts the entity into an equivalent result set simulating the request Any X WHERE X eid _eid_
  • complete(skip_bytes=True)(), executes a request that recovers at once all the missing attributes of an entity
  • get_value(name)(), returns the value associated to the attribute name given in parameter
  • related(rtype, role='subject', limit=None, entities=False)(), returns a list of entities related to the current entity by the relation given in parameter
  • unrelated(rtype, targettype, role='subject', limit=None)(), returns a result set corresponding to the entities not (yet) related to the current entity by the relation given in parameter and satisfying its constraints
  • cw_set(**kwargs)(), updates entity’s attributes and/or relation with the corresponding values given named parameters. To set a relation where this entity is the object of the relation, use reverse_<relation> as argument name. Values may be an entity, a list of entities, or None (meaning that all relations of the given type from or to this object should be deleted).
  • copy_relations(ceid)(), copies the relations of the entities having the eid given in the parameters on the current entity
  • cw_delete() allows to delete the entity

4.2. The AnyEntity class

To provide a specific behavior for each entity, we can define a class inheriting from cubicweb.entities.AnyEntity. In general, we define this class in mycube.entities module (or in a submodule if we want to split code among multiple files) so that it will be available on both server and client side.

The class AnyEntity is a sub-class of Entity that add methods to it, and helps specializing (by further subclassing) the handling of a given entity type.

Most methods defined for AnyEntity, in addition to Entity, add support for the Dublin Core metadata.

Standard meta-data (Dublin Core):

  • dc_title(), returns a unicode string corresponding to the meta-data Title (used by default is the first non-meta attribute of the entity schema)
  • dc_long_title(), same as dc_title but can return a more detailed title
  • dc_description(format='text/plain')(), returns a unicode string corresponding to the meta-data Description (looks for a description attribute by default)
  • dc_authors(), returns a unicode string corresponding to the meta-data Authors (owners by default)
  • dc_creator(), returns a unicode string corresponding to the creator of the entity
  • dc_date(date_format=None)(), returns a unicode string corresponding to the meta-data Date (update date by default)
  • dc_type(form='')(), returns a string to display the entity type by specifying the preferred form (plural for a plural form)
  • dc_language(), returns the language used by the entity

4.3. Inheritance

When describing a data model, entities can inherit from other entities as is common in object-oriented programming.

You have the possibility to redefine whatever pleases you, as follow:

from cubicweb_OTHER_CUBE import entities

class EntityExample(entities.EntityExample):

    def dc_long_title(self):
        return '%s (%s)' % (self.name, self.description)

The most specific entity definition will always the one used by the ORM. For instance, the new EntityExample above in mycube replaces the one in OTHER_CUBE. These types are stored in the etype section of the vregistry.

Notice this is different than yams schema inheritance, which is an experimental undocumented feature.

4.4. Application logic

While a lot of custom behaviour and application logic can be implemented using entity classes, the programmer must be aware that adding new attributes and method on an entity class adds may shadow schema-level attribute or relation definitions.

To keep entities clean (mostly data structures plus a few universal methods such as listed above), one should use adapters (see Interfaces and Adapters).