# evennia.typeclasses.models

This is the abstract django models for many of the database objects in Evennia. A django abstract (obs, not the same as a Python metaclass!) is a model which is not actually created in the database, but which only exists for other models to inherit from, to avoid code duplication. Any model can import and inherit from these classes.

Attributes are database objects stored on other objects. The implementing class needs to supply a ForeignKey field attr_object pointing to the kind of object being mapped. Attributes storing iterables actually store special types of iterables named PackedList/PackedDict respectively. These make sure to save changes to them to database - this is criticial in order to allow for obj.db.mylist[2] = data. Also, all dbobjects are saved as dbrefs but are also aggressively cached.

TypedObjects are objects ‘decorated’ with a typeclass - that is, the typeclass (which is a normal Python class implementing some special tricks with its get/set attribute methods, allows for the creation of all sorts of different objects all with the same database object underneath. Usually attributes are used to permanently store things not hard-coded as field on the database object. The admin should usually not have to deal directly with the database object layer.

This module also contains the Managers for the respective models; inherit from these to create custom managers.

class `evennia.typeclasses.models.``TypedObject`(*args, **kwargs)

  Bases: `evennia.utils.idmapper.models.SharedMemoryModel`

  Abstract Django model.

  This is the basis for a typed object. It also contains all the mechanics for managing connected attributes.

  The TypedObject has the following properties:

  - key - main name

  - name - alias for key

  - typeclass_path - the path to the decorating typeclass

  - typeclass - auto-linked typeclass

  - date_created - time stamp of object creation

  - permissions - perm strings

  - dbref - #id of object

  - db - persistent attribute storage

  - ndb - non-persistent attribute storage

  `db_key`

    A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

  `db_typeclass_path`

    A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

  `db_date_created`

    A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

  `db_lock_storage`

    A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

  `db_attributes`

    Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

    In the example:

        class Pizza(Model):
            toppings = ManyToManyField(Topping, related_name='pizzas')

    **Pizza.toppings** and **Topping.pizzas** are **ManyToManyDescriptor** instances.

    Most of the implementation is delegated to a dynamically defined manager class built by **create_forward_many_to_many_manager()** defined below.

  `db_tags`

    Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

    In the example:

        class Pizza(Model):
            toppings = ManyToManyField(Topping, related_name='pizzas')

    **Pizza.toppings** and **Topping.pizzas** are **ManyToManyDescriptor** instances.

    Most of the implementation is delegated to a dynamically defined manager class built by **create_forward_many_to_many_manager()** defined below.

  `objects`
  `set_class_from_typeclass`(typeclass_path=None)
  `__init__`(*args, **kwargs)

    The __init__ method of typeclasses is the core operational code of the typeclass system, where it dynamically re-applies a class based on the db_typeclass_path database field rather than use the one in the model.

    Parameters

      through to parent. (Passed) –

    Keyword Arguments

      through to parent. (Passed) –

    Notes

    The loading mechanism will attempt the following steps:

    1. Attempt to load typeclass given on command line

    2. Attempt to load typeclass stored in db_typeclass_path

    3. Attempt to load __settingsclasspath__, which is by the default classes defined to be the respective user-set base typeclass settings, like BASE_OBJECT_TYPECLASS.

    4. Attempt to load __defaultclasspath__, which is the base classes in the library, like DefaultObject etc.

    5. If everything else fails, use the database model.

    Normal operation is to load successfully at either step 1 or 2 depending on how the class was called. Tracebacks will be logged for every step the loader must take beyond 2.

  `init_evennia_properties`()

    Called by creation methods; makes sure to initialize Attribute/TagProperties by fetching them once.

  `attributes`
  `locks`
  `tags`
  `aliases`
  `permissions`
  `nattributes`
  class `Meta`

    Bases: `object`

    Django setup info.

    `abstract` = False
    `verbose_name` = 'Evennia Database Object'
    `ordering` = ['-db_date_created', 'id', 'db_typeclass_path', 'db_key']
  property `name`
  property `key`
  property `dbid`

    Caches and returns the unique id of the object. Use this instead of self.id, which is not cached.

  property `dbref`

    Returns the object’s dbref on the form #NN.

  `at_idmapper_flush`()

    This is called when the idmapper cache is flushed and allows customized actions when this happens.

    Returns

      do_flush (bool) –

      If True, flush this object as normal. If

        False, don’t flush and expect this object to handle the flushing on its own.

    Notes

    The default implementation relies on being able to clear Django’s Foreignkey cache on objects not affected by the flush (notably objects with an NAttribute stored). We rely on this cache being stored on the format “_<fieldname>_cache”. If Django were to change this name internally, we need to update here (unlikely, but marking just in case).

  `at_init`()

    Called when this object is loaded into cache. This is more reliable than to override __init__.

  classmethod `search`(query, **kwargs)

    Overridden by class children. This implements a common API.

    Parameters

      - query (str) – A search query.

      - **kwargs – Other search parameters.

    Returns

      list – A list of 0, 1 or more matches, only of this typeclass.

  `is_typeclass`(typeclass, exact=False)

    Returns true if this object has this type OR has a typeclass which is an subclass of the given typeclass. This operates on the actually loaded typeclass (this is important since a failing typeclass may instead have its default currently loaded) typeclass - can be a class object or the python path to such an object to match against.

    Parameters

      - typeclass (str or class) – A class or the full python path to the class to check.

      - exact (bool, optional) – Returns true only if the object’s type is exactly this typeclass, ignoring parents.

    Returns

      is_typeclass (bool) –

      If this typeclass matches the given

        typeclass.

  `swap_typeclass`(new_typeclass, clean_attributes=False, run_start_hooks='all', no_default=True, clean_cmdsets=False)

    This performs an in-situ swap of the typeclass. This means that in-game, this object will suddenly be something else. Account will not be affected. To ‘move’ an account to a different object entirely (while retaining this object’s type), use self.account.swap_object().

    Note that this might be an error prone operation if the old/new typeclass was heavily customized - your code might expect one and not the other, so be careful to bug test your code if using this feature! Often its easiest to create a new object and just swap the account over to that one instead.

    Parameters

      - new_typeclass (str or classobj) – Type to switch to.

      - clean_attributes (bool or list, optional) – Will delete all attributes stored on this object (but not any of the database fields such as name or location). You can’t get attributes back, but this is often the safest bet to make sure nothing in the new typeclass clashes with the old one. If you supply a list, only those named attributes will be cleared.

      - run_start_hooks (str or None, optional) – This is either None, to not run any hooks, “all” to run all hooks defined by at_first_start, or a string with space-separated hook-names to run (for example ‘at_object_creation’). This will always be called without arguments.

      - no_default (bool, optiona) – If set, the swapper will not allow for swapping to a default typeclass in case the given one fails for some reason. Instead the old one will be preserved.

      - clean_cmdsets (bool, optional) – Delete all cmdsets on the object.

  `access`(accessing_obj, access_type='read', default=False, no_superuser_bypass=False, **kwargs)

    Determines if another object has permission to access this one.

    Parameters

      - accessing_obj (str) – Object trying to access this one.

      - access_type (str, optional) – Type of access sought.

      - default (bool, optional) – What to return if no lock of access_type was found

      - no_superuser_bypass (bool, optional) – Turn off the superuser lock bypass (be careful with this one).

    Keyword Arguments

      kwar (any) – Ignored, but is there to make the api consistent with the object-typeclass method access, which use it to feed to its hook methods.

  `check_permstring`(permstring)

    This explicitly checks if we hold particular permission without involving any locks.

    Parameters

      permstring (str) – The permission string to check against.

    Returns

      result (bool) – If the permstring is passed or not.

  `delete`()

    Cleaning up handlers on the typeclass level

  property `db`

    Attribute handler wrapper. Allows for the syntax

        obj.db.attrname = value
        # and
        value = obj.db.attrname
        # and
        del obj.db.attrname
        # and
        all_attr = obj.db.all()
        # (unless there is an attribute
        #  named 'all', in which case that will be returned instead).

  property `ndb`

    NonDataBase). Everything stored to this is guaranteed to be cleared when a server is shutdown. Syntax is same as for the _get_db_holder() method and property, e.g. obj.ndb.attr = value etc.

    Type

      A non-attr_obj store (ndb

  `get_display_name`(looker, **kwargs)

    Displays the name of the object in a viewer-aware manner.

    Parameters

      looker (TypedObject, optional) – The object or account that is looking at/getting inforamtion for this object. If not given, some ‘safe’ minimum level should be returned.

    Returns

      name (str) –

      A string containing the name of the object,

        including the DBREF if this user is privileged to control said object.

    Notes

    This function could be extended to change how object names appear to users in character, but be wary. This function does not change an object’s keys or aliases when searching, and is expected to produce something useful for builders.

  `get_extra_info`(looker, **kwargs)

    Used when an object is in a list of ambiguous objects as an additional information tag.

    For instance, if you had potions which could have varying levels of liquid left in them, you might want to display how many drinks are left in each when selecting which to drop, but not in your normal inventory listing.

    Parameters

      looker (TypedObject) – The object or account that is looking at/getting information for this object.

    Returns

      info (str) –

      A string with disambiguating information,

        conventionally with a leading space.

  `at_rename`(oldname, newname)

    This Hook is called by @name on a successful rename.

    Parameters

      - oldname (str) – The instance’s original name.

      - newname (str) – The new name for the instance.

  `web_get_admin_url`()

    Returns the URI path for the Django Admin page for this object.

    ex. Account#1 = ‘/admin/accounts/accountdb/1/change/’

    Returns

      path (str) – URI path to Django Admin page for object.

  classmethod `web_get_create_url`()

    Returns the URI path for a View that allows users to create new instances of this object.

    ex. Chargen = ‘/characters/create/’

    For this to work, the developer must have defined a named view somewhere in urls.py that follows the format ‘modelname-action’, so in this case a named view of ‘character-create’ would be referenced by this method.

    ex. url(r’characters/create/’, ChargenView.as_view(), name=’character-create’)

    If no View has been created and defined in urls.py, returns an HTML anchor.

    This method is naive and simply returns a path. Securing access to the actual view and limiting who can create new objects is the developer’s responsibility.

    Returns

      path (str) – URI path to object creation page, if defined.

  property `date_created`

    A wrapper for getting database field db_date_created.

  `get_next_by_db_date_created`(*, field=<django.db.models.fields.DateTimeField: db_date_created>, is_next=True, **kwargs)
  `get_previous_by_db_date_created`(*, field=<django.db.models.fields.DateTimeField: db_date_created>, is_next=False, **kwargs)
  property `lock_storage`

    A wrapper for getting database field db_lock_storage.

  `path` = 'evennia.typeclasses.models.TypedObject'
  property `typeclass_path`

    A wrapper for getting database field db_typeclass_path.

  `typename` = 'SharedMemoryModelBase'
  `web_get_detail_url`()

    Returns the URI path for a View that allows users to view details for this object.

    Returns

      path (str) – URI path to object detail page, if defined.

    Examples

        Oscar (Character) = '/characters/oscar/1/'

    For this to work, the developer must have defined a named view somewhere in urls.py that follows the format ‘modelname-action’, so in this case a named view of ‘character-detail’ would be referenced by this method.

        url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$',
            CharDetailView.as_view(), name='character-detail')

    If no View has been created and defined in urls.py, returns an HTML anchor.

    This method is naive and simply returns a path. Securing access to the actual view and limiting who can view this object is the developer’s responsibility.

  `web_get_puppet_url`()

    Returns the URI path for a View that allows users to puppet a specific object.

    Returns

      str – URI path to object puppet page, if defined.

    Examples

        Oscar (Character) = '/characters/oscar/1/puppet/'

    For this to work, the developer must have defined a named view somewhere in urls.py that follows the format ‘modelname-action’, so in this case a named view of ‘character-puppet’ would be referenced by this method.

        url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/puppet/$',
            CharPuppetView.as_view(), name='character-puppet')

    If no View has been created and defined in urls.py, returns an HTML anchor.

    This method is naive and simply returns a path. Securing access to the actual view and limiting who can view this object is the developer’s responsibility.

  `web_get_update_url`()

    Returns the URI path for a View that allows users to update this object.

    Returns

      str – URI path to object update page, if defined.

    Examples

        Oscar (Character) = '/characters/oscar/1/change/'

    For this to work, the developer must have defined a named view somewhere in urls.py that follows the format ‘modelname-action’, so in this case a named view of ‘character-update’ would be referenced by this method.

        url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/change/$',
        CharUpdateView.as_view(), name='character-update')

    If no View has been created and defined in urls.py, returns an HTML anchor.

    This method is naive and simply returns a path. Securing access to the actual view and limiting who can modify objects is the developer’s responsibility.

  `web_get_delete_url`()

    Returns the URI path for a View that allows users to delete this object.

    Returns

      path (str) – URI path to object deletion page, if defined.

    Examples

        Oscar (Character) = '/characters/oscar/1/delete/'

    For this to work, the developer must have defined a named view somewhere in urls.py that follows the format ‘modelname-action’, so in this case a named view of ‘character-detail’ would be referenced by this method.

        url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/delete/$',
        CharDeleteView.as_view(), name='character-delete')

    If no View has been created and defined in urls.py, returns an HTML anchor.

    This method is naive and simply returns a path. Securing access to the actual view and limiting who can delete this object is the developer’s responsibility.

  `get_absolute_url`()

    Returns the URI path for a View that allows users to view details for this object.

    Returns

      path (str) – URI path to object detail page, if defined.

    Examples

        Oscar (Character) = '/characters/oscar/1/'

    For this to work, the developer must have defined a named view somewhere in urls.py that follows the format ‘modelname-action’, so in this case a named view of ‘character-detail’ would be referenced by this method.

        url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$',
            CharDetailView.as_view(), name='character-detail')

    If no View has been created and defined in urls.py, returns an HTML anchor.

    This method is naive and simply returns a path. Securing access to the actual view and limiting who can view this object is the developer’s responsibility.