'Add attribute to object, with optional `lockstring`.
Args:
key (str): An Attribute name to add.
value (any or str): The value of the Attribute. If
`strattr` keyword is set, this *must* be a string.
category (str, optional): The category for the Attribute.
The default `None` is the normal category used.
lockstring (str, optional): A lock string limiting access
to the attribute.
strattr (bool, optional): Make this a string-only Attribute.
This is only ever useful for optimization purposes.
accessing_obj (object, optional): An entity to check for
the `attrcreate` access-type. If not passing, this method
will be exited.
default_access (bool, optional): What access to grant if
`accessing_obj` is given but no lock of the type
`attrcreate` is defined on the Attribute in question.'

def add(self, key, value, category=None, lockstring='', strattr=False, accessing_obj=None, default_access=True):

    if (accessing_obj and (not self.obj.access(accessing_obj, self._attrcreate, default=default_access))):
        return
    if (not key):
        return
    category = (category.strip().lower() if (category is not None) else None)
    keystr = key.strip().lower()
    attr_obj = self._getcache(key, category)
    if attr_obj:
        attr_obj = attr_obj[0]
        if strattr:
            attr_obj.db_strvalue = value
            attr_obj.save(update_fields=['db_strvalue'])
        else:
            attr_obj.value = value
    else:
        kwargs = {'db_key': keystr, 'db_category': category, 'db_model': self._model, 'db_attrtype': self._attrtype, 'db_value': (None if strattr else to_pickle(value)), 'db_strvalue': (value if strattr else None)}
        new_attr = Attribute(**kwargs)
        new_attr.save()
        getattr(self.obj, self._m2m_fieldname).add(new_attr)
        self._setcache(keystr, category, new_attr)
