evennia.web.website package¶
Subpackages¶
Submodules¶
evennia.web.website.forms module¶
-
class
evennia.web.website.forms.AccountForm(*args, **kwargs)[source]¶ Bases:
django.contrib.auth.forms.UserCreationFormThis is a generic Django form tailored to the Account model.
In this incarnation it does not allow getting/setting of attributes, only core User model fields (username, email, password).
-
class
Meta[source]¶ Bases:
objectThis is a Django construct that provides additional configuration to the form.
-
field_classes= {'username': <class 'django.contrib.auth.forms.UsernameField'>}¶
-
fields= ('username', 'email')¶
-
model¶ alias of
typeclasses.accounts.Account
-
-
_meta= <django.forms.models.ModelFormOptions object>¶
-
base_fields= {'email': <django.forms.fields.EmailField object>, 'password1': <django.forms.fields.CharField object>, 'password2': <django.forms.fields.CharField object>, 'username': <django.contrib.auth.forms.UsernameField object>}¶
-
declared_fields= {'email': <django.forms.fields.EmailField object>, 'password1': <django.forms.fields.CharField object>, 'password2': <django.forms.fields.CharField object>}¶
-
property
media¶
-
class
-
class
evennia.web.website.forms.CharacterForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)[source]¶ Bases:
evennia.web.website.forms.ObjectFormThis is a Django form for Evennia Character objects.
Since Evennia characters only have one attribute by default, this form only defines a field for that single attribute. The names of fields you define should correspond to their names as stored in the dbhandler; you can display ‘prettier’ versions of the fieldname on the form using the ‘label’ kwarg.
The basic field types are CharFields and IntegerFields, which let you enter text and numbers respectively. IntegerFields have some neat validation tricks they can do, like mandating values fall within a certain range.
For example, a complete “age” field (which stores its value to character.db.age might look like:
- age = forms.IntegerField(
label=”Your Age”, min_value=18, max_value=9000, help_text=”Years since your birth.”)
Default input fields are generic single-line text boxes. You can control what sort of input field users will see by specifying a “widget.” An example of this is used for the ‘desc’ field to show a Textarea box instead of a Textbox.
For help in building out your form, please see: https://docs.djangoproject.com/en/1.11/topics/forms/#building-a-form-in-django
For more information on fields and their capabilities, see: https://docs.djangoproject.com/en/1.11/ref/forms/fields/
For more on widgets, see: https://docs.djangoproject.com/en/1.11/ref/forms/widgets/
-
class
Meta[source]¶ Bases:
objectThis is a Django construct that provides additional configuration to the form.
-
fields= ('db_key',)¶
-
labels= {'db_key': 'Name'}¶
-
model¶ alias of
typeclasses.characters.Character
-
-
_meta= <django.forms.models.ModelFormOptions object>¶
-
base_fields= {'db_key': <django.forms.fields.CharField object>, 'desc': <django.forms.fields.CharField object>}¶
-
declared_fields= {'desc': <django.forms.fields.CharField object>}¶
-
property
media¶
-
class
evennia.web.website.forms.CharacterUpdateForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)[source]¶ Bases:
evennia.web.website.forms.CharacterFormThis is a Django form for updating Evennia Character objects.
By default it is the same as the CharacterForm, but if there are circumstances in which you don’t want to let players edit all the same attributes they had access to during creation, you can redefine this form with those fields you do wish to allow.
-
_meta= <django.forms.models.ModelFormOptions object>¶
-
base_fields= {'db_key': <django.forms.fields.CharField object>, 'desc': <django.forms.fields.CharField object>}¶
-
declared_fields= {'desc': <django.forms.fields.CharField object>}¶
-
property
media¶
-
-
class
evennia.web.website.forms.EvenniaForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)[source]¶ Bases:
django.forms.forms.FormThis is a stock Django form, but modified so that all values provided through it are escaped (sanitized). Validation is performed by the fields you define in the form.
This has little to do with Evennia itself and is more general web security- related.
https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet#Goals_of_Input_Validation
-
base_fields= {}¶
-
clean()[source]¶ Django hook. Performed on form submission.
- Returns
Dictionary of key:value pairs submitted on the form.
- Return type
cleaned (dict)
-
declared_fields= {}¶
-
property
media¶
-
-
class
evennia.web.website.forms.ObjectForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)[source]¶ Bases:
evennia.web.website.forms.EvenniaForm,django.forms.models.ModelFormThis is a Django form for generic Evennia Objects that allows modification of attributes when called from a descendent of ObjectUpdate or ObjectCreate views.
It defines no fields by default; you have to do that by extending this class and defining what fields you want to be recorded. See the CharacterForm for a simple example of how to do this.
-
class
Meta[source]¶ Bases:
objectThis is a Django construct that provides additional configuration to the form.
-
fields= ('db_key',)¶
-
labels= {'db_key': 'Name'}¶
-
model¶ alias of
typeclasses.objects.Object
-
-
_meta= <django.forms.models.ModelFormOptions object>¶
-
base_fields= {'db_key': <django.forms.fields.CharField object>}¶
-
declared_fields= {}¶
-
property
media¶
-
class
evennia.web.website.tests module¶
-
class
evennia.web.website.tests.AdminTest(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
unauthenticated_response= 302¶
-
url_name= 'django_admin'¶
-
-
class
evennia.web.website.tests.ChannelDetailTest(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
url_name= 'channel-detail'¶
-
-
class
evennia.web.website.tests.ChannelListTest(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
url_name= 'channels'¶
-
-
class
evennia.web.website.tests.CharacterCreateView(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
test_valid_access_multisession_0()[source]¶ Account1 with no characters should be able to create a new one
-
unauthenticated_response= 302¶
-
url_name= 'character-create'¶
-
-
class
evennia.web.website.tests.CharacterDeleteView(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
unauthenticated_response= 302¶
-
url_name= 'character-delete'¶
-
-
class
evennia.web.website.tests.CharacterListView(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
unauthenticated_response= 302¶
-
url_name= 'characters'¶
-
-
class
evennia.web.website.tests.CharacterManageView(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
unauthenticated_response= 302¶
-
url_name= 'character-manage'¶
-
-
class
evennia.web.website.tests.CharacterPuppetView(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
unauthenticated_response= 302¶
-
url_name= 'character-puppet'¶
-
-
class
evennia.web.website.tests.CharacterUpdateView(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
unauthenticated_response= 302¶
-
url_name= 'character-update'¶
-
-
class
evennia.web.website.tests.EvenniaWebTest(methodName='runTest')[source]¶ Bases:
evennia.utils.test_resources.EvenniaTest-
account_typeclass= 'typeclasses.accounts.Account'¶
-
authenticated_response= 200¶
-
channel_typeclass= 'typeclasses.channels.Channel'¶
-
character_typeclass= 'typeclasses.characters.Character'¶
-
exit_typeclass= 'typeclasses.exits.Exit'¶
-
object_typeclass= 'typeclasses.objects.Object'¶
-
room_typeclass= 'typeclasses.rooms.Room'¶
-
script_typeclass= 'typeclasses.scripts.Script'¶
-
unauthenticated_response= 200¶
-
url_name= 'index'¶
-
-
class
evennia.web.website.tests.IndexTest(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
url_name= 'index'¶
-
-
class
evennia.web.website.tests.LoginTest(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
url_name= 'login'¶
-
-
class
evennia.web.website.tests.LogoutTest(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
url_name= 'logout'¶
-
-
class
evennia.web.website.tests.PasswordResetTest(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
unauthenticated_response= 302¶
-
url_name= 'password_change'¶
-
-
class
evennia.web.website.tests.RegisterTest(methodName='runTest')[source]¶ Bases:
evennia.web.website.tests.EvenniaWebTest-
url_name= 'register'¶
-
evennia.web.website.urls module¶
This structures the website.
evennia.web.website.views module¶
This file contains the generic, assorted views that don’t fall under one of the other applications. Views are django’s way of processing e.g. html templates on the fly.
-
class
evennia.web.website.views.AccountCreateView(**kwargs)[source]¶ Bases:
evennia.web.website.views.AccountMixin,evennia.web.website.views.EvenniaCreateViewAccount creation view.
-
form_valid(form)[source]¶ Django hook, modified for Evennia.
This hook is called after a valid form is submitted.
When an account creation form is submitted and the data is deemed valid, proceeds with creating the Account object.
-
success_url= '/auth/login/'¶
-
template_name= 'website/registration/register.html'¶
-
-
class
evennia.web.website.views.AccountMixin[source]¶ Bases:
evennia.web.website.views.TypeclassMixinThis is a “mixin”, a modifier of sorts.
Any view class with this in its inheritance list will be modified to work with Account objects instead of generic Objects or otherwise.
-
form_class¶
-
model¶ alias of
typeclasses.accounts.Account
-
-
class
evennia.web.website.views.ChannelDetailView(**kwargs)[source]¶ Bases:
evennia.web.website.views.ChannelMixin,evennia.web.website.views.ObjectDetailViewReturns the log entries for a given channel.
-
attributes= ['name']¶
-
get_context_data(**kwargs)[source]¶ Django hook; before we can display the channel logs, we need to recall the logfile and read its lines.
- Returns
Django context object
- Return type
context (dict)
-
get_object(queryset=None)[source]¶ Override of Django hook that retrieves an object by slugified channel name.
- Returns
Channel requested in the URL.
- Return type
channel (Channel)
-
max_num_lines= 10000¶
-
template_name= 'website/channel_detail.html'¶
-
-
class
evennia.web.website.views.ChannelListView(**kwargs)[source]¶ Bases:
evennia.web.website.views.ChannelMixin,django.views.generic.list.ListViewReturns a list of channels that can be viewed by a user, authenticated or not.
-
get_context_data(**kwargs)[source]¶ Django hook; we override it to calculate the most popular channels.
- Returns
Django context object
- Return type
context (dict)
-
max_popular= 10¶
-
page_title= 'Channel Index'¶
-
paginate_by= 100¶
-
template_name= 'website/channel_list.html'¶
-
-
class
evennia.web.website.views.ChannelMixin[source]¶ Bases:
evennia.web.website.views.TypeclassMixinThis is a “mixin”, a modifier of sorts.
Any view class with this in its inheritance list will be modified to work with HelpEntry objects instead of generic Objects or otherwise.
-
access_type= 'listen'¶
-
get_queryset()[source]¶ Django hook; here we want to return a list of only those Channels and other documentation that the current user is allowed to see.
- Returns
List of Channels available to the user.
- Return type
queryset (QuerySet)
-
model¶ alias of
typeclasses.channels.Channel
-
page_title= 'Channels'¶
-
-
class
evennia.web.website.views.CharacterCreateView(**kwargs)[source]¶ Bases:
evennia.web.website.views.CharacterMixin,evennia.web.website.views.ObjectCreateViewThis view provides a mechanism by which a logged-in player (enforced by ObjectCreateView) can create a new character.
-
form_valid(form)[source]¶ Django hook, modified for Evennia.
This hook is called after a valid form is submitted.
When an character creation form is submitted and the data is deemed valid, proceeds with creating the Character object.
-
template_name= 'website/character_form.html'¶
-
-
class
evennia.web.website.views.CharacterDeleteView(**kwargs)[source]¶ Bases:
evennia.web.website.views.CharacterMixin,evennia.web.website.views.ObjectDeleteViewThis view provides a mechanism by which a logged-in player (enforced by ObjectDeleteView) can delete a character they own.
-
class
evennia.web.website.views.CharacterDetailView(**kwargs)[source]¶ Bases:
evennia.web.website.views.CharacterMixin,evennia.web.website.views.ObjectDetailViewThis view provides a mechanism by which a user can view the attributes of a character, owned by them or not.
-
access_type= 'view'¶
-
attributes= ['name', 'desc']¶
-
get_queryset()[source]¶ This method will override the Django get_queryset method to return a list of all characters the user may access.
- Returns
Django queryset for use in the given view.
- Return type
queryset (QuerySet)
-
template_name= 'website/object_detail.html'¶
-
-
class
evennia.web.website.views.CharacterListView(**kwargs)[source]¶ Bases:
django.contrib.auth.mixins.LoginRequiredMixin,evennia.web.website.views.CharacterMixin,django.views.generic.list.ListViewThis view provides a mechanism by which a logged-in player can view a list of all other characters.
This view requires authentication by default as a nominal effort to prevent human stalkers and automated bots/scrapers from harvesting data on your users.
-
access_type= 'view'¶
-
get_queryset()[source]¶ This method will override the Django get_queryset method to return a list of all characters (filtered/sorted) instead of just those limited to the account.
- Returns
Django queryset for use in the given view.
- Return type
queryset (QuerySet)
-
page_title= 'Character List'¶
-
paginate_by= 100¶
-
template_name= 'website/character_list.html'¶
-
-
class
evennia.web.website.views.CharacterManageView(**kwargs)[source]¶ Bases:
django.contrib.auth.mixins.LoginRequiredMixin,evennia.web.website.views.CharacterMixin,django.views.generic.list.ListViewThis view provides a mechanism by which a logged-in player can browse, edit, or delete their own characters.
-
page_title= 'Manage Characters'¶
-
paginate_by= 10¶
-
template_name= 'website/character_manage_list.html'¶
-
-
class
evennia.web.website.views.CharacterMixin[source]¶ Bases:
evennia.web.website.views.TypeclassMixinThis is a “mixin”, a modifier of sorts.
Any view class with this in its inheritance list will be modified to work with Character objects instead of generic Objects or otherwise.
-
form_class¶
-
get_queryset()[source]¶ This method will override the Django get_queryset method to only return a list of characters associated with the current authenticated user.
- Returns
Django queryset for use in the given view.
- Return type
queryset (QuerySet)
-
model¶ alias of
typeclasses.characters.Character
-
success_url= '/characters/manage/'¶
-
-
class
evennia.web.website.views.CharacterPuppetView(**kwargs)[source]¶ Bases:
django.contrib.auth.mixins.LoginRequiredMixin,evennia.web.website.views.CharacterMixin,django.views.generic.base.RedirectView,evennia.web.website.views.ObjectDetailViewThis view provides a mechanism by which a logged-in player can “puppet” one of their characters within the context of the website.
It also ensures that any user attempting to puppet something is logged in, and that their intended puppet is one that they own.
-
class
evennia.web.website.views.CharacterUpdateView(**kwargs)[source]¶ Bases:
evennia.web.website.views.CharacterMixin,evennia.web.website.views.ObjectUpdateViewThis view provides a mechanism by which a logged-in player (enforced by ObjectUpdateView) can edit the attributes of a character they own.
-
form_class¶
-
template_name= 'website/character_form.html'¶
-
-
class
evennia.web.website.views.EvenniaCreateView(**kwargs)[source]¶ Bases:
django.views.generic.edit.CreateView,evennia.web.website.views.TypeclassMixinThis view extends Django’s default CreateView.
CreateView is used for creating new objects, be they Accounts, Characters or otherwise.
-
property
page_title¶
-
property
-
class
evennia.web.website.views.EvenniaDeleteView(**kwargs)[source]¶ Bases:
django.views.generic.edit.DeleteView,evennia.web.website.views.TypeclassMixinThis view extends Django’s default DeleteView.
DeleteView is used for deleting objects, be they Accounts, Characters or otherwise.
-
property
page_title¶
-
property
-
class
evennia.web.website.views.EvenniaDetailView(**kwargs)[source]¶ Bases:
django.views.generic.detail.DetailView,evennia.web.website.views.TypeclassMixinThis view extends Django’s default DetailView.
DetailView is used for displaying objects, be they Accounts, Characters or otherwise.
-
property
page_title¶
-
property
-
class
evennia.web.website.views.EvenniaIndexView(**kwargs)[source]¶ Bases:
django.views.generic.base.TemplateViewThis is a basic example of a Django class-based view, which are functionally very similar to Evennia Commands but differ in structure. Commands are used to interface with users using a terminal client. Views are used to interface with users using a web browser.
To use a class-based view, you need to have written a template in HTML, and then you write a view like this to tell Django what values to display on it.
While there are simpler ways of writing views using plain functions (and Evennia currently contains a few examples of them), just like Commands, writing views as classes provides you with more flexibility– you can extend classes and change things to suit your needs rather than having to copy and paste entire code blocks over and over. Django also comes with many default views for displaying things, all of them implemented as classes.
This particular example displays the index page.
-
get_context_data(**kwargs)[source]¶ This is a common Django method. Think of this as the website equivalent of the Evennia Command.func() method.
If you just want to display a static page with no customization, you don’t need to define this method– just create a view, define template_name and you’re done.
The only catch here is that if you extend or overwrite this method, you’ll always want to make sure you call the parent method to get a context object. It’s just a dict, but it comes prepopulated with all sorts of background data intended for display on the page.
You can do whatever you want to it, but it must be returned at the end of this method.
- Kwargs:
any (any): Passed through.
- Returns
Dictionary of data you want to display on the page.
- Return type
context (dict)
-
template_name= 'website/index.html'¶
-
-
class
evennia.web.website.views.EvenniaUpdateView(**kwargs)[source]¶ Bases:
django.views.generic.edit.UpdateView,evennia.web.website.views.TypeclassMixinThis view extends Django’s default UpdateView.
UpdateView is used for updating objects, be they Accounts, Characters or otherwise.
-
property
page_title¶
-
property
-
class
evennia.web.website.views.HelpDetailView(**kwargs)[source]¶ Bases:
evennia.web.website.views.HelpMixin,evennia.web.website.views.EvenniaDetailViewReturns the detail page for a given help entry.
-
get_context_data(**kwargs)[source]¶ Adds navigational data to the template to let browsers go to the next or previous entry in the help list.
- Returns
Django context object
- Return type
context (dict)
-
get_object(queryset=None)[source]¶ Override of Django hook that retrieves an object by category and topic instead of pk and slug.
- Returns
HelpEntry requested in the URL.
- Return type
entry (HelpEntry)
-
template_name= 'website/help_detail.html'¶
-
-
class
evennia.web.website.views.HelpListView(**kwargs)[source]¶ Bases:
evennia.web.website.views.HelpMixin,django.views.generic.list.ListViewReturns a list of help entries that can be viewed by a user, authenticated or not.
-
page_title= 'Help Index'¶
-
paginate_by= 500¶
-
template_name= 'website/help_list.html'¶
-
-
class
evennia.web.website.views.HelpMixin[source]¶ Bases:
evennia.web.website.views.TypeclassMixinThis is a “mixin”, a modifier of sorts.
Any view class with this in its inheritance list will be modified to work with HelpEntry objects instead of generic Objects or otherwise.
-
get_queryset()[source]¶ Django hook; here we want to return a list of only those HelpEntries and other documentation that the current user is allowed to see.
- Returns
List of Help entries available to the user.
- Return type
queryset (QuerySet)
-
model¶ alias of
evennia.help.models.HelpEntry
-
page_title= 'Help'¶
-
-
class
evennia.web.website.views.ObjectCreateView(**kwargs)[source]¶ Bases:
django.contrib.auth.mixins.LoginRequiredMixin,evennia.web.website.views.EvenniaCreateViewThis is an important view.
Any view you write that deals with creating a specific object will want to inherit from this. It provides the mechanisms by which to make sure the user requesting creation of an object is authenticated, and provides a sane default title for the page.
-
model¶ alias of
typeclasses.objects.Object
-
-
class
evennia.web.website.views.ObjectDeleteView(**kwargs)[source]¶ Bases:
django.contrib.auth.mixins.LoginRequiredMixin,evennia.web.website.views.ObjectDetailView,evennia.web.website.views.EvenniaDeleteViewThis is an important view for obvious reasons!
Any view you write that deals with deleting a specific object will want to inherit from this. It provides the mechanisms by which to make sure the user requesting deletion of an object is authenticated, and that they have permissions to delete the requested object.
-
access_type= 'delete'¶
-
delete(request, *args, **kwargs)[source]¶ Calls the delete() method on the fetched object and then redirects to the success URL.
We extend this so we can capture the name for the sake of confirmation.
-
model¶ alias of
typeclasses.objects.Object
-
template_name= 'website/object_confirm_delete.html'¶
-
-
class
evennia.web.website.views.ObjectDetailView(**kwargs)[source]¶ Bases:
evennia.web.website.views.EvenniaDetailViewThis is an important view.
Any view you write that deals with displaying, updating or deleting a specific object will want to inherit from this. It provides the mechanisms by which to retrieve the object and make sure the user requesting it has permissions to actually do things to it.
-
access_type= 'view'¶
-
attributes= ['name', 'desc']¶
-
get_context_data(**kwargs)[source]¶ Adds an ‘attributes’ list to the request context consisting of the attributes specified at the class level, and in the order provided.
Django views do not provide a way to reference dynamic attributes, so we have to grab them all before we render the template.
- Returns
Django context object
- Return type
context (dict)
-
get_object(queryset=None)[source]¶ Override of Django hook that provides some important Evennia-specific functionality.
Evennia does not natively store slugs, so where a slug is provided, calculate the same for the object and make sure it matches.
This also checks to make sure the user has access to view/edit/delete this object!
-
model¶ alias of
typeclasses.objects.Object
-
template_name= 'website/object_detail.html'¶
-
-
class
evennia.web.website.views.ObjectUpdateView(**kwargs)[source]¶ Bases:
django.contrib.auth.mixins.LoginRequiredMixin,evennia.web.website.views.ObjectDetailView,evennia.web.website.views.EvenniaUpdateViewThis is an important view.
Any view you write that deals with updating a specific object will want to inherit from this. It provides the mechanisms by which to make sure the user requesting editing of an object is authenticated, and that they have permissions to edit the requested object.
This functions slightly different from default Django UpdateViews in that it does not update core model fields, only object attributes!
-
access_type= 'edit'¶
-
form_valid(form)[source]¶ Override of Django hook.
Updates object attributes based on values submitted.
This is run when the form is submitted and the data on it is deemed valid– all values are within expected ranges, all strings contain valid characters and lengths, etc.
This method is only called if all values for the fields submitted passed form validation, so at this point we can assume the data is validated and sanitized.
-
get_initial()[source]¶ Django hook, modified for Evennia.
Prepopulates the update form field values based on object db attributes.
- Returns
- Dictionary of key:value pairs containing initial form
data.
- Return type
data (dict)
-
get_success_url()[source]¶ Django hook.
Can be overridden to return any URL you want to redirect the user to after the object is successfully updated, but by default it goes to the object detail page so the user can see their changes reflected.
-
model¶ alias of
typeclasses.objects.Object
-
-
class
evennia.web.website.views.TypeclassMixin[source]¶ Bases:
objectThis is a “mixin”, a modifier of sorts.
Django views typically work with classes called “models.” Evennia objects are an enhancement upon these Django models and are called “typeclasses.” But Django itself has no idea what a “typeclass” is.
For the sake of mitigating confusion, any view class with this in its inheritance list will be modified to work with Evennia Typeclass objects or Django models interchangeably.
-
property
typeclass¶
-
property