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, b
(model)
| 67 | |
| 68 | |
| 69 | def get_related_models_recursive(model): |
| 70 | """ |
| 71 | Return all models that have a direct or indirect relationship |
| 72 | to the given model. |
| 73 | |
| 74 | Relationships are either defined by explicit relational fields, like |
| 75 | ForeignKey, ManyToManyField or OneToOneField, or by inheriting from another |
| 76 | model (a superclass is related to its subclasses, but not vice versa). |
| 77 | Note, however, that a model inheriting from a concrete model is also |
| 78 | related to its superclass through the implicit *_ptr OneToOneField on the |
| 79 | subclass. |
| 80 | """ |
| 81 | seen = set() |
| 82 | queue = _get_related_models(model) |
| 83 | for rel_mod in queue: |
| 84 | rel_app_label, rel_model_name = ( |
| 85 | rel_mod._meta.app_label, |
| 86 | rel_mod._meta.model_name, |
| 87 | ) |
| 88 | if (rel_app_label, rel_model_name) in seen: |
| 89 | continue |
| 90 | seen.add((rel_app_label, rel_model_name)) |
| 91 | queue.extend(_get_related_models(rel_mod)) |
| 92 | return seen - {(model._meta.app_label, model._meta.model_name)} |
| 93 | |
| 94 | |
| 95 | class ProjectState: |