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)[source]

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)[source]
__init__(*args, **kwargs)[source]

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()[source]

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

attributes[source]
locks[source]
tags[source]
aliases[source]
permissions[source]
nattributes[source]
class Meta[source]

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 date_created

Get the localized date created, based on settings.TIME_ZONE.

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()[source]

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()[source]

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

classmethod search(query, **kwargs)[source]

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)[source]

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)[source]

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)[source]

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)[source]

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()[source]

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)[source]

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)[source]

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)[source]

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()[source]

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()[source]

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.

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()[source]

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()[source]

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()[source]

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()[source]

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.