This modules provides a layer to decouple resource field types from the view factory that will generate the views for the repository items.
These objects just serve as metadata, they do not do anything and do not depend on any specific library. They are here just to serve as a common vocabulary between plugins to know what kind of object a field is.
It is the responsability of the rum.interfaces.IRepositoryFactory implementation to provide this metadata about the resources it knows how to handle.
Two distinct plugins that depend on each other just to share a definition of a Field should get in touch to get the Field declaration included here in order to decouple from each other.
Returns a dict with default values to populate an instance of resource.
Associates a series of rum.fields.Field instances to a model class.
This rum.fields.Field are queried by the rum.view.ViewFactory and give it a hint on how it should generate the interface.
It can be placed right in the model class it assigns metadata to like a “class decorator”:
>>> class Peanut(object):
... FieldFactory.fields(
... Unicode("name", required=True),
... Integer("weight")
... )
Or the binding can be done elsewhere (anywhere both the model and fields can be imported). This is useful to avoid contaminating your models with Rum imports:
>>> class Orange(object):
... pass
Then in some other module:
>>> FieldFactory.fields(Orange, [
... Unicode("name", required=True),
... Integer("weight")
... ])
<class 'rum.fields.Orange'>
Note
This module needs to be imported somehow since if it’s not the fields will not be registered and Rum will try to guess them.
Both ways are equivalent, use the one you find more pleasing to the eye or allows you to structure your code better.
Notice that (in both situations) the original class is returned as-is, it is not modified in any way (the registry lives inside PEAK-Rules if you’re wondering)
There’s a third syntax to override just one field:
>>> FieldFactory.fields(Orange, "weight", Unicode("weight"))
<class 'rum.fields.Orange'>
Fields registered this way will override fields registered in any of the other two ways.
Note
Remember, the View can do whatever it feels like with this information. These are just hints.
Returns a rum.fields.Field subclass.
attribute of resource objects should always be set by this function
attribute of resource objects should always be fetched by this function
This Field holds a boolean value
Examples:
>>> Boolean(name='name')
rum.fields.Boolean(name='name', required=False, label='Name', default=NoDefault, read_only=False, searchable=False, sortable=True, description='')
This Relation represents a relation to a collection of objects
Examples:
>>> class Related: pass
>>> Collection(name='name', other=Related, remote_name='related')
rum.fields.Collection(name='name', other=<class rum.fields.Related at ...>, remote_name='related', required=False, label='Name', default=NoDefault, read_only=False, searchable=False, sortable=False, description='', expression='')
This Field represents a date
Examples:
>>> Date(name='pub_date')
rum.fields.Date(name='pub_date', required=False, label='Pub date', default=NoDefault, read_only=False, sortable=True, searchable=False, description='')
This Field represents a time with an associated date.
Examples:
>>> DateTime(name='name', has_timezone=True)
rum.fields.DateTime(name='name', required=False, label='Name', default=NoDefault, read_only=False, has_timezone=True, sortable=True, searchable=False, description='')
This Field holds a real number
Examples:
>>> Decimal(name='name', range=(10,50), precision=10)
rum.fields.Decimal(name='name', required=False, label='Name', default=NoDefault, read_only=False, range=(10, 50), precision=10, sortable=True, searchable=True, description='')
This Field is a String but signals the GUI and validation framework that is should contain a valid email address.
Examples:
>>> Email(name='name', length=50)
rum.fields.Email(name='name', required=False, label='Name', default=NoDefault, read_only=False, length=50, sortable=True, searchable=True, description='')
A field base class
Examples:
>>> Field(name='name')
rum.fields.Field(name='name', required=False, label='Name', default=NoDefault, read_only=False, searchable=False, sortable=False, description='')
This Field represents a foreign key. It normally signals the GUI not to render it at all and use the associated Relation instead.
It’s name and required flag are derived from type
Examples:
>>> ForeignKey(Integer('id'))
rum.fields.ForeignKey(type=rum.fields.Integer(name='id', required=False, label='Id', default=NoDefault, read_only=False, range=(None, None), sortable=True, searchable=True, description=''), order=None, searchable=False, target='')
>>> ForeignKey(Integer('id', required=True, description=''), order=0)
rum.fields.ForeignKey(type=rum.fields.Integer(name='id', required=True, label='Id', default=NoDefault, read_only=False, range=(None, None), sortable=True, searchable=True, description=''), order=0, searchable=False, target='')
This Field is a UnicodeText but the GUI should render some sort of fancy control to edit HTML.
Examples:
>>> HTMLText(name='name', length=50)
rum.fields.HTMLText(name='name', required=False, label='Name', default=NoDefault, read_only=False, length=50, sortable=True, searchable=True, description='')
This Field is a Number that can only hold int or long numbers.
Examples:
>>> Integer(name='name', range=(10,50))
rum.fields.Integer(name='name', required=False, label='Name', default=NoDefault, read_only=False, range=(10, 50), sortable=True, searchable=True, description='')
This Field represents a field which is an implementation detail. An should not be shown in the GUI.
Examples:
>>> InternalField(Integer('id'))
rum.fields.InternalField(type=rum.fields.Integer(name='id', required=False, label='Id', default=NoDefault, read_only=False, range=(None, None), sortable=True, searchable=True, description=''), searchable=False, description='')
This Relation represents a relation to an ordered list of objects
Examples:
>>> class Related: pass
>>> List(name='name', other=Related, remote_name='related', expression='')
rum.fields.List(name='name', other=<class rum.fields.Related at ...>, remote_name='related', required=False, label='Name', default=NoDefault, read_only=False, searchable=False, sortable=False, description='', expression='')
This Relation represents a relation to mapping of objects by some key. (think of a dictionary)
Examples:
>>> class Related: pass
>>> Mapping(name='name', other=Related, remote_name='related')
rum.fields.Mapping(name='name', other=<class rum.fields.Related at ...>, remote_name='related', required=False, label='Name', default=NoDefault, read_only=False, searchable=False, sortable=False, description='', expression='')
This Field holds a number
Examples:
>>> Number(name='name', range=(10,50))
rum.fields.Number(name='name', required=False, label='Name', default=NoDefault, read_only=False, range=(10, 50), sortable=True, searchable=True, description='')
This Field is a Unicode which holds a password. It signals the GUI to handle it in a special way (eg: by not showing it, etc...)
Examples:
>>> Password(name='password', length=50)
rum.fields.Password(name='password', required=False, label='Password', default=NoDefault, read_only=False, length=50, sortable=False, searchable=False, description='')
This Field represents a polymorphic discriminator. This makes sense for SQLAlchemy really but other backend might find it useful perhaps.
>>> PolymorphicDiscriminator(String('type'))
rum.fields.PolymorphicDiscriminator(type=rum.fields.String(name='type', required=False, label='Type', default=NoDefault, read_only=False, length=None, sortable=True, searchable=True, description=''), searchable=False, description='')
This Field is a PreformattedText, which should use html pre tags when displayed.
Examples:
>>> PreformattedText(name='name', length=50)
rum.fields.PreformattedText(name='name', required=False, label='Name', default=NoDefault, read_only=False, length=50, sortable=True, searchable=True, description='')
This Field represents a primary key. It normally signals the GUI to render a disabled field or not render it at all on edit forms.
If it is autogenerated then it will probably not be rendered at all.
Examples:
>>> PrimaryKey(Integer('id'))
rum.fields.PrimaryKey(type=rum.fields.Integer(name='id', required=True, label='Id', default=NoDefault, read_only=False, range=(None, None), sortable=True, searchable=True, description=''), auto=True, order=None)
>>> PrimaryKey(Integer('id'), auto=False)
rum.fields.PrimaryKey(type=rum.fields.Integer(name='id', required=True, label='Id', default=NoDefault, read_only=False, range=(None, None), sortable=True, searchable=True, description=''), auto=False, order=None)
This Field represents a field of a related object. An should not be shown in the GUI.
>>> class Foo(object): pass
>>> RelatedField(real_field=Integer('id'), related_to=Relation('foo', other=Foo, remote_name=None), label='foo.id')
rum.fields.RelatedField(related_to=rum.fields.Relation(name='foo', other=<class 'rum.fields.Foo'>, remote_name=None, required=False, label='Foo', default=NoDefault, read_only=False, searchable=False, sortable=False, description='', expression=''), real_field=rum.fields.Integer(name='id', required=False, label='Id', default=NoDefault, read_only=False, range=(None, None), sortable=True, searchable=True, description=''), label='foo.id')
for person.address.town return Person class, the next resource in the chain of the relation. This in encapsulated deep in the field >>> class Person(object): pass >>> class Address(object): pass >>> class town(object): pass >>> f=RelatedField(related_to=RelatedField( related_to=Relation(name=’person’, remote_name=None, other=Person), real_field=Relation(name=’address’, remote_name=None, other=Address), label=’person.address’ ), real_field=String(name=’town’), label=’person.address.town’) >>> f.next_relation_in_chain() rum.fields.Relation(name=’person’, other=<class ‘rum.fields.Person’>, remote_name=None, required=False, label=’Person’, default=NoDefault, read_only=False, searchable=False, sortable=False, description=’‘, expression=’‘)
This Field represents a relation to another object
Examples:
>>> class Related: pass
>>> Relation(name='name', other=Related, remote_name='related')
rum.fields.Relation(name='name', other=<class rum.fields.Related at ...>, remote_name='related', required=False, label='Name', default=NoDefault, read_only=False, searchable=False, sortable=False, description='', expression='')
This Field represents an ascii string.
Examples:
>>> String(name='name', length=50)
rum.fields.String(name='name', required=False, label='Name', default=NoDefault, read_only=False, length=50, sortable=True, searchable=True, description='')
This Field is a String but the GUI should render a textarea of some other sort of control to manipulate a chunk of text.
Examples:
>>> Text(name='name', length=50)
rum.fields.Text(name='name', required=False, label='Name', default=NoDefault, read_only=False, length=50, sortable=True, searchable=True, description='')
This Field represents a time
Examples:
>>> Time(name='name', has_timezone=True)
rum.fields.Time(name='name', required=False, label='Name', default=NoDefault, read_only=False, has_timezone=True, sortable=True, searchable=False, description='')
This Field represents a relation to another object
Examples:
>>> class Related: pass
>>> ToOneRelation(name='name', other=Related, remote_name='related')
rum.fields.ToOneRelation(name='name', other=<class rum.fields.Related at ...>, remote_name='related', required=False, label='Name', default=NoDefault, read_only=False, searchable=False, sortable=False, description='', expression='')
This Field is a String but can hold unicode strings.
Examples:
>>> Unicode(name='name', length=50, description='foo')
rum.fields.Unicode(name='name', required=False, label='Name', default=NoDefault, read_only=False, length=50, sortable=True, searchable=True, description='foo')
This Field is a Unicode but the GUI should render a textarea of some other sort of control to manipulate a chunk of text.
Examples:
>>> Unicode(name='name', length=50)
rum.fields.Unicode(name='name', required=False, label='Name', default=NoDefault, read_only=False, length=50, sortable=True, searchable=True, description='')
This Field is a String but signals the GUI and validation framework that is should contain a valid URL.
Examples:
>>> Url(name='name', length=50)
rum.fields.Url(name='name', required=False, label='Name', default=NoDefault, read_only=False, length=50, sortable=True, searchable=True, description='')
This Field represents a version id field used implement optimistic locking of model instances to avoid concurrent modification. This makes sense for SQLAlchemy really but other backend might find it useful too.
>>> VersionID(Integer('version'))
rum.fields.VersionID(type=rum.fields.Integer(name='version', required=False, label='Version', default=NoDefault, read_only=False, range=(None, None), sortable=True, searchable=True, description=''), searchable=False, description='')