'Get all objects having the given attrname set to the given value.
Args:
attribute_name (str): Attribute key to search for.
attribute_value (str):  Attribute value to search for.
candidates (list, optional): Candidate objects to limit search to.
typeclasses (list, optional): Python pats to restrict matches with.
Returns:
matches (list): Objects fullfilling both the `attribute_name` and `attribute_value` criterions.
Notes:
This uses the Attribute\'s PickledField to transparently search the database by matching
the internal representation. This is reasonably effective but since Attribute values
cannot be indexed, searching by Attribute key is to be preferred whenever possible.'

@returns_typeclass_list
def get_objs_with_attr_value(self, attribute_name, attribute_value, candidates=None, typeclasses=None):

    cand_restriction = (((candidates is not None) and Q(pk__in=[_GA(obj, 'id') for obj in make_iter(candidates) if obj])) or Q())
    type_restriction = ((typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses))) or Q())
    if isinstance(attribute_value, (basestring, int, float, bool)):
        return self.filter(((cand_restriction & type_restriction) & Q(db_attributes__db_key=attribute_name, db_attributes__db_value=attribute_value)))
    else:
        global _ATTR
        if (not _ATTR):
            from evennia.typeclasses.models import Attribute as _ATTR
        cands = list(self.filter(((cand_restriction & type_restriction) & Q(db_attributes__db_key=attribute_name))))
        results = [attr.objectdb_set.all() for attr in _ATTR.objects.filter(objectdb__in=cands, db_value=attribute_value)]
        return chain(*results)
