# evennia.web.admin.attributes

Attribute admin.

Note that we don’t present a separate admin for these, since they are only relevant together with a specific object.

class `evennia.web.admin.attributes.``AttributeForm`(*args, **kwargs)

  Bases: `django.forms.models.ModelForm`

  This form overrides the base behavior of the ModelForm that would be used for a Attribute-through-model. Since the through-models only have access to the foreignkeys of the Attribute and the Object that they’re attached to, we need to spoof the behavior of it being a form that would correspond to its Attribute, or the creation of an Attribute. Instead of being saved, we’ll call to the Object’s handler, which will handle the creation, change, or deletion of an Attribute for us, as well as updating the handler’s cache so that all changes are instantly updated in-game.

  class `Meta`

    Bases: `object`

    `fields` = ('attr_key', 'attr_value', 'attr_category', 'attr_lockstring', 'attr_type')
  `__init__`(*args, **kwargs)

    If we have an Attribute, then we’ll prepopulate our instance with the fields we’d expect it to have based on the Attribute. attr_key, attr_category, attr_value, attr_type, and attr_lockstring all refer to the corresponding Attribute fields. The initial data of the form fields will similarly be populated.

  `save`(commit=True)

    One thing we want to do here is the or None checks, because forms are saved with an empty string rather than null from forms, usually, and the Handlers may handle empty strings differently than None objects. So for consistency with how things are handled in game, we’ll try to make sure that empty form fields will be None, rather than ‘’.

  `clean_attr_value`()

    Prevent certain data-types from being cleaned due to literal_eval failing on them. Otherwise they will be turned into str.

  `base_fields` = {'attr_category': <django.forms.fields.CharField object>, 'attr_key': <django.forms.fields.CharField object>, 'attr_lockstring': <django.forms.fields.CharField object>, 'attr_type': <django.forms.fields.ChoiceField object>, 'attr_value': <evennia.utils.picklefield.PickledFormField object>}
  `declared_fields` = {'attr_category': <django.forms.fields.CharField object>, 'attr_key': <django.forms.fields.CharField object>, 'attr_lockstring': <django.forms.fields.CharField object>, 'attr_type': <django.forms.fields.ChoiceField object>, 'attr_value': <evennia.utils.picklefield.PickledFormField object>}
  property `media`

    Return all media required to render the widgets on this form.

class `evennia.web.admin.attributes.``AttributeFormSet`(data=None, files=None, instance=None, save_as_new=False, prefix=None, queryset=None, **kwargs)

  Bases: `django.forms.models.BaseInlineFormSet`

  Attribute version of TagFormSet, as above.

  `save`(commit=True)

    Save model instances for every form, adding and changing instances as necessary, and return the list of instances.

class `evennia.web.admin.attributes.``AttributeInline`(parent_model, admin_site)

  Bases: `django.contrib.admin.options.TabularInline`

  A handler for inline Attributes. This class should be subclassed in the admin of your models, and the ‘model’ and ‘related_field’ class attributes must be set. model should be the through model (ObjectDB_db_tag’, for example), while related field should be the name of the field on that through model which points to the model being used: ‘objectdb’, ‘msg’, ‘accountdb’, etc.

  `model` = None
  `verbose_name` = 'Attribute'
  `verbose_name_plural` = 'Attributes'
  `form`

    alias of `AttributeForm`

  `formset`

    alias of `AttributeFormSet`

  `related_field` = None
  `extra` = 0
  `get_formset`(request, obj=None, **kwargs)

    get_formset has to return a class, but we need to make the class that we return know about the related_field that we’ll use. Returning the class itself rather than a proxy isn’t threadsafe, since it’d be the base class and would change if multiple people used the admin at the same time

  property `media`