Commit 2ee67f03 authored by Simon Charette's avatar Simon Charette
Browse files

Moved an inner function in db.migrations.state to avoid redefinition.

parent 63f0e2df
Loading
Loading
Loading
Loading
+24 −20
Original line number Diff line number Diff line
@@ -29,18 +29,10 @@ def _get_app_label_and_model_name(model, app_label=''):
        return model._meta.app_label, model._meta.model_name


def get_related_models_recursive(model):
def _get_related_models(m):
    """
    Returns all models that have a direct or indirect relationship
    to the given model.

    Relationships are either defined by explicit relational fields, like
    ForeignKey, ManyToManyField or OneToOneField, or by inheriting from another
    model (a superclass is related to its subclasses, but not vice versa). Note,
    however, that a model inheriting from a concrete model is also related to
    its superclass through the implicit *_ptr OneToOneField on the subclass.
    Return all models that have a direct relationship to the given model.
    """
    def _related_models(m):
    related_models = [
        subclass for subclass in m.__subclasses__()
        if issubclass(subclass, models.Model)
@@ -50,21 +42,33 @@ def get_related_models_recursive(model):
        if f.is_relation and f.related_model is not None and not isinstance(f.related_model, six.string_types):
            related_fields_models.add(f.model)
            related_models.append(f.related_model)
        # Reverse accessors of foreign keys to proxy models
        # are attached to their concrete proxied model.
    # Reverse accessors of foreign keys to proxy models are attached to their
    # concrete proxied model.
    opts = m._meta
    if opts.proxy and m in related_fields_models:
        related_models.append(opts.concrete_model)
    return related_models


def get_related_models_recursive(model):
    """
    Return all models that have a direct or indirect relationship
    to the given model.

    Relationships are either defined by explicit relational fields, like
    ForeignKey, ManyToManyField or OneToOneField, or by inheriting from another
    model (a superclass is related to its subclasses, but not vice versa). Note,
    however, that a model inheriting from a concrete model is also related to
    its superclass through the implicit *_ptr OneToOneField on the subclass.
    """
    seen = set()
    queue = _related_models(model)
    queue = _get_related_models(model)
    for rel_mod in queue:
        rel_app_label, rel_model_name = rel_mod._meta.app_label, rel_mod._meta.model_name
        if (rel_app_label, rel_model_name) in seen:
            continue
        seen.add((rel_app_label, rel_model_name))
        queue.extend(_related_models(rel_mod))
        queue.extend(_get_related_models(rel_mod))
    return seen - {(model._meta.app_label, model._meta.model_name)}