Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/polymorphic/utils.py: 15%
38 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from django.contrib.contenttypes.models import ContentType
2from django.db import DEFAULT_DB_ALIAS
4from polymorphic.base import PolymorphicModelBase
5from polymorphic.models import PolymorphicModel
8def reset_polymorphic_ctype(*models, **filters):
9 """
10 Set the polymorphic content-type ID field to the proper model
11 Sort the ``*models`` from base class to descending class,
12 to make sure the content types are properly assigned.
14 Add ``ignore_existing=True`` to skip models which already
15 have a polymorphic content type.
16 """
17 using = filters.pop("using", DEFAULT_DB_ALIAS)
18 ignore_existing = filters.pop("ignore_existing", False)
20 models = sort_by_subclass(*models)
21 if ignore_existing:
22 # When excluding models, make sure we don't ignore the models we
23 # just assigned the an content type to. hence, start with child first.
24 models = reversed(models)
26 for new_model in models:
27 new_ct = ContentType.objects.db_manager(using).get_for_model(
28 new_model, for_concrete_model=False
29 )
31 qs = new_model.objects.db_manager(using)
32 if ignore_existing:
33 qs = qs.filter(polymorphic_ctype__isnull=True)
34 if filters:
35 qs = qs.filter(**filters)
36 qs.update(polymorphic_ctype=new_ct)
39def _compare_mro(cls1, cls2):
40 if cls1 is cls2:
41 return 0
43 try:
44 index1 = cls1.mro().index(cls2)
45 except ValueError:
46 return -1 # cls2 not inherited by 1
48 try:
49 index2 = cls2.mro().index(cls1)
50 except ValueError:
51 return 1 # cls1 not inherited by 2
53 return (index1 > index2) - (index1 < index2) # python 3 compatible cmp.
56def sort_by_subclass(*classes):
57 """
58 Sort a series of models by their inheritance order.
59 """
60 from functools import cmp_to_key
62 return sorted(classes, key=cmp_to_key(_compare_mro))
65def get_base_polymorphic_model(ChildModel, allow_abstract=False):
66 """
67 First the first concrete model in the inheritance chain that inherited from the PolymorphicModel.
68 """
69 for Model in reversed(ChildModel.mro()):
70 if (
71 isinstance(Model, PolymorphicModelBase)
72 and Model is not PolymorphicModel
73 and (allow_abstract or not Model._meta.abstract)
74 ):
75 return Model
76 return None