You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

utils.py 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. from collections import namedtuple
  2. from django.db.models.fields.related import RECURSIVE_RELATIONSHIP_CONSTANT
  3. def is_referenced_by_foreign_key(state, model_name_lower, field, field_name):
  4. for state_app_label, state_model in state.models:
  5. for _, f in state.models[state_app_label, state_model].fields:
  6. if (f.related_model and
  7. '%s.%s' % (state_app_label, model_name_lower) == f.related_model.lower() and
  8. hasattr(f, 'to_fields')):
  9. if (f.to_fields[0] is None and field.primary_key) or field_name in f.to_fields:
  10. return True
  11. return False
  12. class ModelTuple(namedtuple('ModelTupleBase', ('app_label', 'model_name'))):
  13. @classmethod
  14. def from_model(cls, model, app_label=None, model_name=None):
  15. """
  16. Take a model class or a 'app_label.ModelName' string and return a
  17. ModelTuple('app_label', 'modelname'). The optional app_label and
  18. model_name arguments are the defaults if "self" or "ModelName" are
  19. passed.
  20. """
  21. if isinstance(model, str):
  22. if model == RECURSIVE_RELATIONSHIP_CONSTANT:
  23. return cls(app_label, model_name)
  24. if '.' in model:
  25. return cls(*model.lower().split('.', 1))
  26. return cls(app_label, model.lower())
  27. return cls(model._meta.app_label, model._meta.model_name)
  28. def __eq__(self, other):
  29. if isinstance(other, ModelTuple):
  30. # Consider ModelTuple equal if their model_name is equal and either
  31. # one of them is missing an app_label.
  32. return self.model_name == other.model_name and (
  33. self.app_label is None or other.app_label is None or self.app_label == other.app_label
  34. )
  35. return super().__eq__(other)
  36. def field_references_model(field, model_tuple):
  37. """Return whether or not field references model_tuple."""
  38. remote_field = field.remote_field
  39. if remote_field:
  40. if ModelTuple.from_model(remote_field.model) == model_tuple:
  41. return True
  42. through = getattr(remote_field, 'through', None)
  43. if through and ModelTuple.from_model(through) == model_tuple:
  44. return True
  45. return False