1. from django.db import models
    
  2. from django.template import Context, Template
    
  3. from django.test import SimpleTestCase, TestCase, override_settings
    
  4. from django.test.utils import isolate_apps
    
  5. 
    
  6. from .models import (
    
  7.     AbstractBase1,
    
  8.     AbstractBase2,
    
  9.     AbstractBase3,
    
  10.     Child1,
    
  11.     Child2,
    
  12.     Child3,
    
  13.     Child4,
    
  14.     Child5,
    
  15.     Child6,
    
  16.     Child7,
    
  17.     RelatedModel,
    
  18.     RelationModel,
    
  19. )
    
  20. 
    
  21. 
    
  22. class ManagersRegressionTests(TestCase):
    
  23.     def test_managers(self):
    
  24.         a1 = Child1.objects.create(name="fred", data="a1")
    
  25.         a2 = Child1.objects.create(name="barney", data="a2")
    
  26.         b1 = Child2.objects.create(name="fred", data="b1", value=1)
    
  27.         b2 = Child2.objects.create(name="barney", data="b2", value=42)
    
  28.         c1 = Child3.objects.create(name="fred", data="c1", comment="yes")
    
  29.         c2 = Child3.objects.create(name="barney", data="c2", comment="no")
    
  30.         d1 = Child4.objects.create(name="fred", data="d1")
    
  31.         d2 = Child4.objects.create(name="barney", data="d2")
    
  32.         fred1 = Child5.objects.create(name="fred", comment="yes")
    
  33.         Child5.objects.create(name="barney", comment="no")
    
  34.         f1 = Child6.objects.create(name="fred", data="f1", value=42)
    
  35.         f2 = Child6.objects.create(name="barney", data="f2", value=42)
    
  36.         fred2 = Child7.objects.create(name="fred")
    
  37.         barney = Child7.objects.create(name="barney")
    
  38. 
    
  39.         self.assertSequenceEqual(Child1.manager1.all(), [a1])
    
  40.         self.assertSequenceEqual(Child1.manager2.all(), [a2])
    
  41.         self.assertSequenceEqual(Child1._default_manager.all(), [a1])
    
  42. 
    
  43.         self.assertSequenceEqual(Child2._default_manager.all(), [b1])
    
  44.         self.assertSequenceEqual(Child2.restricted.all(), [b2])
    
  45. 
    
  46.         self.assertSequenceEqual(Child3._default_manager.all(), [c1])
    
  47.         self.assertSequenceEqual(Child3.manager1.all(), [c1])
    
  48.         self.assertSequenceEqual(Child3.manager2.all(), [c2])
    
  49. 
    
  50.         # Since Child6 inherits from Child4, the corresponding rows from f1 and
    
  51.         # f2 also appear here. This is the expected result.
    
  52.         self.assertSequenceEqual(
    
  53.             Child4._default_manager.order_by("data"),
    
  54.             [d1, d2, f1.child4_ptr, f2.child4_ptr],
    
  55.         )
    
  56.         self.assertCountEqual(Child4.manager1.all(), [d1, f1.child4_ptr])
    
  57.         self.assertCountEqual(Child5._default_manager.all(), [fred1])
    
  58.         self.assertCountEqual(Child6._default_manager.all(), [f1, f2])
    
  59.         self.assertSequenceEqual(
    
  60.             Child7._default_manager.order_by("name"),
    
  61.             [barney, fred2],
    
  62.         )
    
  63. 
    
  64.     def test_abstract_manager(self):
    
  65.         # Accessing the manager on an abstract model should
    
  66.         # raise an attribute error with an appropriate message.
    
  67.         # This error message isn't ideal, but if the model is abstract and
    
  68.         # a lot of the class instantiation logic isn't invoked; if the
    
  69.         # manager is implied, then we don't get a hook to install the
    
  70.         # error-raising manager.
    
  71.         msg = "type object 'AbstractBase3' has no attribute 'objects'"
    
  72.         with self.assertRaisesMessage(AttributeError, msg):
    
  73.             AbstractBase3.objects.all()
    
  74. 
    
  75.     def test_custom_abstract_manager(self):
    
  76.         # Accessing the manager on an abstract model with a custom
    
  77.         # manager should raise an attribute error with an appropriate
    
  78.         # message.
    
  79.         msg = "Manager isn't available; AbstractBase2 is abstract"
    
  80.         with self.assertRaisesMessage(AttributeError, msg):
    
  81.             AbstractBase2.restricted.all()
    
  82. 
    
  83.     def test_explicit_abstract_manager(self):
    
  84.         # Accessing the manager on an abstract model with an explicit
    
  85.         # manager should raise an attribute error with an appropriate
    
  86.         # message.
    
  87.         msg = "Manager isn't available; AbstractBase1 is abstract"
    
  88.         with self.assertRaisesMessage(AttributeError, msg):
    
  89.             AbstractBase1.objects.all()
    
  90. 
    
  91.     @override_settings(TEST_SWAPPABLE_MODEL="managers_regress.Parent")
    
  92.     @isolate_apps("managers_regress")
    
  93.     def test_swappable_manager(self):
    
  94.         class SwappableModel(models.Model):
    
  95.             class Meta:
    
  96.                 swappable = "TEST_SWAPPABLE_MODEL"
    
  97. 
    
  98.         # Accessing the manager on a swappable model should
    
  99.         # raise an attribute error with a helpful message
    
  100.         msg = (
    
  101.             "Manager isn't available; 'managers_regress.SwappableModel' "
    
  102.             "has been swapped for 'managers_regress.Parent'"
    
  103.         )
    
  104.         with self.assertRaisesMessage(AttributeError, msg):
    
  105.             SwappableModel.objects.all()
    
  106. 
    
  107.     @override_settings(TEST_SWAPPABLE_MODEL="managers_regress.Parent")
    
  108.     @isolate_apps("managers_regress")
    
  109.     def test_custom_swappable_manager(self):
    
  110.         class SwappableModel(models.Model):
    
  111.             stuff = models.Manager()
    
  112. 
    
  113.             class Meta:
    
  114.                 swappable = "TEST_SWAPPABLE_MODEL"
    
  115. 
    
  116.         # Accessing the manager on a swappable model with an
    
  117.         # explicit manager should raise an attribute error with a
    
  118.         # helpful message
    
  119.         msg = (
    
  120.             "Manager isn't available; 'managers_regress.SwappableModel' "
    
  121.             "has been swapped for 'managers_regress.Parent'"
    
  122.         )
    
  123.         with self.assertRaisesMessage(AttributeError, msg):
    
  124.             SwappableModel.stuff.all()
    
  125. 
    
  126.     @override_settings(TEST_SWAPPABLE_MODEL="managers_regress.Parent")
    
  127.     @isolate_apps("managers_regress")
    
  128.     def test_explicit_swappable_manager(self):
    
  129.         class SwappableModel(models.Model):
    
  130.             objects = models.Manager()
    
  131. 
    
  132.             class Meta:
    
  133.                 swappable = "TEST_SWAPPABLE_MODEL"
    
  134. 
    
  135.         # Accessing the manager on a swappable model with an
    
  136.         # explicit manager should raise an attribute error with a
    
  137.         # helpful message
    
  138.         msg = (
    
  139.             "Manager isn't available; 'managers_regress.SwappableModel' "
    
  140.             "has been swapped for 'managers_regress.Parent'"
    
  141.         )
    
  142.         with self.assertRaisesMessage(AttributeError, msg):
    
  143.             SwappableModel.objects.all()
    
  144. 
    
  145.     def test_regress_3871(self):
    
  146.         related = RelatedModel.objects.create()
    
  147. 
    
  148.         relation = RelationModel()
    
  149.         relation.fk = related
    
  150.         relation.gfk = related
    
  151.         relation.save()
    
  152.         relation.m2m.add(related)
    
  153. 
    
  154.         t = Template(
    
  155.             "{{ related.test_fk.all.0 }}{{ related.test_gfk.all.0 }}"
    
  156.             "{{ related.test_m2m.all.0 }}"
    
  157.         )
    
  158. 
    
  159.         self.assertEqual(
    
  160.             t.render(Context({"related": related})),
    
  161.             "".join([str(relation.pk)] * 3),
    
  162.         )
    
  163. 
    
  164.     def test_field_can_be_called_exact(self):
    
  165.         # Make sure related managers core filters don't include an
    
  166.         # explicit `__exact` lookup that could be interpreted as a
    
  167.         # reference to a foreign `exact` field. refs #23940.
    
  168.         related = RelatedModel.objects.create(exact=False)
    
  169.         relation = related.test_fk.create()
    
  170.         self.assertEqual(related.test_fk.get(), relation)
    
  171. 
    
  172. 
    
  173. @isolate_apps("managers_regress")
    
  174. class TestManagerInheritance(SimpleTestCase):
    
  175.     def test_implicit_inheritance(self):
    
  176.         class CustomManager(models.Manager):
    
  177.             pass
    
  178. 
    
  179.         class AbstractModel(models.Model):
    
  180.             custom_manager = CustomManager()
    
  181. 
    
  182.             class Meta:
    
  183.                 abstract = True
    
  184. 
    
  185.         class PlainModel(models.Model):
    
  186.             custom_manager = CustomManager()
    
  187. 
    
  188.         self.assertIsInstance(PlainModel._base_manager, models.Manager)
    
  189.         self.assertIsInstance(PlainModel._default_manager, CustomManager)
    
  190. 
    
  191.         class ModelWithAbstractParent(AbstractModel):
    
  192.             pass
    
  193. 
    
  194.         self.assertIsInstance(ModelWithAbstractParent._base_manager, models.Manager)
    
  195.         self.assertIsInstance(ModelWithAbstractParent._default_manager, CustomManager)
    
  196. 
    
  197.         class ProxyModel(PlainModel):
    
  198.             class Meta:
    
  199.                 proxy = True
    
  200. 
    
  201.         self.assertIsInstance(ProxyModel._base_manager, models.Manager)
    
  202.         self.assertIsInstance(ProxyModel._default_manager, CustomManager)
    
  203. 
    
  204.         class MTIModel(PlainModel):
    
  205.             pass
    
  206. 
    
  207.         self.assertIsInstance(MTIModel._base_manager, models.Manager)
    
  208.         self.assertIsInstance(MTIModel._default_manager, CustomManager)
    
  209. 
    
  210.     def test_default_manager_inheritance(self):
    
  211.         class CustomManager(models.Manager):
    
  212.             pass
    
  213. 
    
  214.         class AbstractModel(models.Model):
    
  215.             another_manager = models.Manager()
    
  216.             custom_manager = CustomManager()
    
  217. 
    
  218.             class Meta:
    
  219.                 default_manager_name = "custom_manager"
    
  220.                 abstract = True
    
  221. 
    
  222.         class PlainModel(models.Model):
    
  223.             another_manager = models.Manager()
    
  224.             custom_manager = CustomManager()
    
  225. 
    
  226.             class Meta:
    
  227.                 default_manager_name = "custom_manager"
    
  228. 
    
  229.         self.assertIsInstance(PlainModel._default_manager, CustomManager)
    
  230. 
    
  231.         class ModelWithAbstractParent(AbstractModel):
    
  232.             pass
    
  233. 
    
  234.         self.assertIsInstance(ModelWithAbstractParent._default_manager, CustomManager)
    
  235. 
    
  236.         class ProxyModel(PlainModel):
    
  237.             class Meta:
    
  238.                 proxy = True
    
  239. 
    
  240.         self.assertIsInstance(ProxyModel._default_manager, CustomManager)
    
  241. 
    
  242.         class MTIModel(PlainModel):
    
  243.             pass
    
  244. 
    
  245.         self.assertIsInstance(MTIModel._default_manager, CustomManager)
    
  246. 
    
  247.     def test_base_manager_inheritance(self):
    
  248.         class CustomManager(models.Manager):
    
  249.             pass
    
  250. 
    
  251.         class AbstractModel(models.Model):
    
  252.             another_manager = models.Manager()
    
  253.             custom_manager = CustomManager()
    
  254. 
    
  255.             class Meta:
    
  256.                 base_manager_name = "custom_manager"
    
  257.                 abstract = True
    
  258. 
    
  259.         class PlainModel(models.Model):
    
  260.             another_manager = models.Manager()
    
  261.             custom_manager = CustomManager()
    
  262. 
    
  263.             class Meta:
    
  264.                 base_manager_name = "custom_manager"
    
  265. 
    
  266.         self.assertIsInstance(PlainModel._base_manager, CustomManager)
    
  267. 
    
  268.         class ModelWithAbstractParent(AbstractModel):
    
  269.             pass
    
  270. 
    
  271.         self.assertIsInstance(ModelWithAbstractParent._base_manager, CustomManager)
    
  272. 
    
  273.         class ProxyModel(PlainModel):
    
  274.             class Meta:
    
  275.                 proxy = True
    
  276. 
    
  277.         self.assertIsInstance(ProxyModel._base_manager, CustomManager)
    
  278. 
    
  279.         class MTIModel(PlainModel):
    
  280.             pass
    
  281. 
    
  282.         self.assertIsInstance(MTIModel._base_manager, CustomManager)
    
  283. 
    
  284.     def test_manager_no_duplicates(self):
    
  285.         class CustomManager(models.Manager):
    
  286.             pass
    
  287. 
    
  288.         class AbstractModel(models.Model):
    
  289.             custom_manager = models.Manager()
    
  290. 
    
  291.             class Meta:
    
  292.                 abstract = True
    
  293. 
    
  294.         class TestModel(AbstractModel):
    
  295.             custom_manager = CustomManager()
    
  296. 
    
  297.         self.assertEqual(TestModel._meta.managers, (TestModel.custom_manager,))
    
  298.         self.assertEqual(
    
  299.             TestModel._meta.managers_map, {"custom_manager": TestModel.custom_manager}
    
  300.         )
    
  301. 
    
  302.     def test_manager_class_getitem(self):
    
  303.         self.assertIs(models.Manager[Child1], models.Manager)