Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
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.3KB

1 year ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from django.contrib.contenttypes.models import ContentType
  2. from django.db import DEFAULT_DB_ALIAS
  3. from polymorphic.base import PolymorphicModelBase
  4. from polymorphic.models import PolymorphicModel
  5. def reset_polymorphic_ctype(*models, **filters):
  6. """
  7. Set the polymorphic content-type ID field to the proper model
  8. Sort the ``*models`` from base class to descending class,
  9. to make sure the content types are properly assigned.
  10. Add ``ignore_existing=True`` to skip models which already
  11. have a polymorphic content type.
  12. """
  13. using = filters.pop("using", DEFAULT_DB_ALIAS)
  14. ignore_existing = filters.pop("ignore_existing", False)
  15. models = sort_by_subclass(*models)
  16. if ignore_existing:
  17. # When excluding models, make sure we don't ignore the models we
  18. # just assigned the an content type to. hence, start with child first.
  19. models = reversed(models)
  20. for new_model in models:
  21. new_ct = ContentType.objects.db_manager(using).get_for_model(
  22. new_model, for_concrete_model=False
  23. )
  24. qs = new_model.objects.db_manager(using)
  25. if ignore_existing:
  26. qs = qs.filter(polymorphic_ctype__isnull=True)
  27. if filters:
  28. qs = qs.filter(**filters)
  29. qs.update(polymorphic_ctype=new_ct)
  30. def _compare_mro(cls1, cls2):
  31. if cls1 is cls2:
  32. return 0
  33. try:
  34. index1 = cls1.mro().index(cls2)
  35. except ValueError:
  36. return -1 # cls2 not inherited by 1
  37. try:
  38. index2 = cls2.mro().index(cls1)
  39. except ValueError:
  40. return 1 # cls1 not inherited by 2
  41. return (index1 > index2) - (index1 < index2) # python 3 compatible cmp.
  42. def sort_by_subclass(*classes):
  43. """
  44. Sort a series of models by their inheritance order.
  45. """
  46. from functools import cmp_to_key
  47. return sorted(classes, key=cmp_to_key(_compare_mro))
  48. def get_base_polymorphic_model(ChildModel, allow_abstract=False):
  49. """
  50. First the first concrete model in the inheritance chain that inherited from the PolymorphicModel.
  51. """
  52. for Model in reversed(ChildModel.mro()):
  53. if (
  54. isinstance(Model, PolymorphicModelBase)
  55. and Model is not PolymorphicModel
  56. and (allow_abstract or not Model._meta.abstract)
  57. ):
  58. return Model
  59. return None