'Determines if the objects in the given queryset-like can be
fast-deleted. This can be done if there are no cascades, no
parents and no signal listeners for the object class.
The \'from_field\' tells where we are coming from - we need this to
determine if the objects are in fact to be deleted. Allows also
skipping parent -> child -> parent chain preventing fast delete of
the child.'

def can_fast_delete(self, objs, from_field=None):

    if (from_field and (from_field.rel.on_delete is not CASCADE)):
        return False
    if (not (hasattr(objs, 'model') and hasattr(objs, '_raw_delete'))):
        return False
    model = objs.model
    if (signals.pre_delete.has_listeners(model) or signals.post_delete.has_listeners(model) or signals.m2m_changed.has_listeners(model)):
        return False
    opts = model._meta
    if any(((link != from_field) for link in opts.concrete_model._meta.parents.values())):
        return False
    for related in opts.get_all_related_objects(include_hidden=True, include_proxy_eq=True):
        if (related.field.rel.on_delete is not DO_NOTHING):
            return False
    for relation in opts.many_to_many:
        if (not relation.rel.through):
            return False
    return True
