1. from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
    
  2. from django.contrib.contenttypes.models import ContentType
    
  3. from django.db import models
    
  4. 
    
  5. 
    
  6. class Relation(models.Model):
    
  7.     pass
    
  8. 
    
  9. 
    
  10. class InstanceOnlyDescriptor:
    
  11.     def __get__(self, instance, cls=None):
    
  12.         if instance is None:
    
  13.             raise AttributeError("Instance only")
    
  14.         return 1
    
  15. 
    
  16. 
    
  17. class AbstractPerson(models.Model):
    
  18.     # DATA fields
    
  19.     data_abstract = models.CharField(max_length=10)
    
  20.     fk_abstract = models.ForeignKey(
    
  21.         Relation, models.CASCADE, related_name="fk_abstract_rel"
    
  22.     )
    
  23. 
    
  24.     # M2M fields
    
  25.     m2m_abstract = models.ManyToManyField(Relation, related_name="m2m_abstract_rel")
    
  26.     friends_abstract = models.ManyToManyField("self", symmetrical=True)
    
  27.     following_abstract = models.ManyToManyField(
    
  28.         "self", related_name="followers_abstract", symmetrical=False
    
  29.     )
    
  30. 
    
  31.     # VIRTUAL fields
    
  32.     data_not_concrete_abstract = models.ForeignObject(
    
  33.         Relation,
    
  34.         on_delete=models.CASCADE,
    
  35.         from_fields=["abstract_non_concrete_id"],
    
  36.         to_fields=["id"],
    
  37.         related_name="fo_abstract_rel",
    
  38.     )
    
  39. 
    
  40.     # GFK fields
    
  41.     content_type_abstract = models.ForeignKey(
    
  42.         ContentType, models.CASCADE, related_name="+"
    
  43.     )
    
  44.     object_id_abstract = models.PositiveIntegerField()
    
  45.     content_object_abstract = GenericForeignKey(
    
  46.         "content_type_abstract", "object_id_abstract"
    
  47.     )
    
  48. 
    
  49.     # GR fields
    
  50.     generic_relation_abstract = GenericRelation(Relation)
    
  51. 
    
  52.     class Meta:
    
  53.         abstract = True
    
  54. 
    
  55.     @property
    
  56.     def test_property(self):
    
  57.         return 1
    
  58. 
    
  59.     test_instance_only_descriptor = InstanceOnlyDescriptor()
    
  60. 
    
  61. 
    
  62. class BasePerson(AbstractPerson):
    
  63.     # DATA fields
    
  64.     data_base = models.CharField(max_length=10)
    
  65.     fk_base = models.ForeignKey(Relation, models.CASCADE, related_name="fk_base_rel")
    
  66. 
    
  67.     # M2M fields
    
  68.     m2m_base = models.ManyToManyField(Relation, related_name="m2m_base_rel")
    
  69.     friends_base = models.ManyToManyField("self", symmetrical=True)
    
  70.     following_base = models.ManyToManyField(
    
  71.         "self", related_name="followers_base", symmetrical=False
    
  72.     )
    
  73. 
    
  74.     # VIRTUAL fields
    
  75.     data_not_concrete_base = models.ForeignObject(
    
  76.         Relation,
    
  77.         on_delete=models.CASCADE,
    
  78.         from_fields=["base_non_concrete_id"],
    
  79.         to_fields=["id"],
    
  80.         related_name="fo_base_rel",
    
  81.     )
    
  82. 
    
  83.     # GFK fields
    
  84.     content_type_base = models.ForeignKey(ContentType, models.CASCADE, related_name="+")
    
  85.     object_id_base = models.PositiveIntegerField()
    
  86.     content_object_base = GenericForeignKey("content_type_base", "object_id_base")
    
  87. 
    
  88.     # GR fields
    
  89.     generic_relation_base = GenericRelation(Relation)
    
  90. 
    
  91. 
    
  92. class Person(BasePerson):
    
  93.     # DATA fields
    
  94.     data_inherited = models.CharField(max_length=10)
    
  95.     fk_inherited = models.ForeignKey(
    
  96.         Relation, models.CASCADE, related_name="fk_concrete_rel"
    
  97.     )
    
  98. 
    
  99.     # M2M Fields
    
  100.     m2m_inherited = models.ManyToManyField(Relation, related_name="m2m_concrete_rel")
    
  101.     friends_inherited = models.ManyToManyField("self", symmetrical=True)
    
  102.     following_inherited = models.ManyToManyField(
    
  103.         "self", related_name="followers_concrete", symmetrical=False
    
  104.     )
    
  105. 
    
  106.     # VIRTUAL fields
    
  107.     data_not_concrete_inherited = models.ForeignObject(
    
  108.         Relation,
    
  109.         on_delete=models.CASCADE,
    
  110.         from_fields=["model_non_concrete_id"],
    
  111.         to_fields=["id"],
    
  112.         related_name="fo_concrete_rel",
    
  113.     )
    
  114. 
    
  115.     # GFK fields
    
  116.     content_type_concrete = models.ForeignKey(
    
  117.         ContentType, models.CASCADE, related_name="+"
    
  118.     )
    
  119.     object_id_concrete = models.PositiveIntegerField()
    
  120.     content_object_concrete = GenericForeignKey(
    
  121.         "content_type_concrete", "object_id_concrete"
    
  122.     )
    
  123. 
    
  124.     # GR fields
    
  125.     generic_relation_concrete = GenericRelation(Relation)
    
  126. 
    
  127. 
    
  128. class ProxyPerson(Person):
    
  129.     class Meta:
    
  130.         proxy = True
    
  131. 
    
  132. 
    
  133. class PersonThroughProxySubclass(ProxyPerson):
    
  134.     pass
    
  135. 
    
  136. 
    
  137. class Relating(models.Model):
    
  138.     # ForeignKey to BasePerson
    
  139.     baseperson = models.ForeignKey(
    
  140.         BasePerson, models.CASCADE, related_name="relating_baseperson"
    
  141.     )
    
  142.     baseperson_hidden = models.ForeignKey(BasePerson, models.CASCADE, related_name="+")
    
  143. 
    
  144.     # ForeignKey to Person
    
  145.     person = models.ForeignKey(Person, models.CASCADE, related_name="relating_person")
    
  146.     person_hidden = models.ForeignKey(Person, models.CASCADE, related_name="+")
    
  147. 
    
  148.     # ForeignKey to ProxyPerson
    
  149.     proxyperson = models.ForeignKey(
    
  150.         ProxyPerson, models.CASCADE, related_name="relating_proxyperson"
    
  151.     )
    
  152.     proxyperson_hidden = models.ForeignKey(
    
  153.         ProxyPerson, models.CASCADE, related_name="relating_proxyperson_hidden+"
    
  154.     )
    
  155. 
    
  156.     # ManyToManyField to BasePerson
    
  157.     basepeople = models.ManyToManyField(BasePerson, related_name="relating_basepeople")
    
  158.     basepeople_hidden = models.ManyToManyField(BasePerson, related_name="+")
    
  159. 
    
  160.     # ManyToManyField to Person
    
  161.     people = models.ManyToManyField(Person, related_name="relating_people")
    
  162.     people_hidden = models.ManyToManyField(Person, related_name="+")
    
  163. 
    
  164. 
    
  165. # ParentListTests models
    
  166. class CommonAncestor(models.Model):
    
  167.     pass
    
  168. 
    
  169. 
    
  170. class FirstParent(CommonAncestor):
    
  171.     first_ancestor = models.OneToOneField(
    
  172.         CommonAncestor, models.CASCADE, primary_key=True, parent_link=True
    
  173.     )
    
  174. 
    
  175. 
    
  176. class SecondParent(CommonAncestor):
    
  177.     second_ancestor = models.OneToOneField(
    
  178.         CommonAncestor, models.CASCADE, primary_key=True, parent_link=True
    
  179.     )
    
  180. 
    
  181. 
    
  182. class Child(FirstParent, SecondParent):
    
  183.     pass