1. import threading
    
  2. from datetime import datetime, timedelta
    
  3. from unittest import mock
    
  4. 
    
  5. from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
    
  6. from django.db import DEFAULT_DB_ALIAS, DatabaseError, connections, models
    
  7. from django.db.models.manager import BaseManager
    
  8. from django.db.models.query import MAX_GET_RESULTS, EmptyQuerySet
    
  9. from django.test import (
    
  10.     SimpleTestCase,
    
  11.     TestCase,
    
  12.     TransactionTestCase,
    
  13.     skipUnlessDBFeature,
    
  14. )
    
  15. from django.utils.translation import gettext_lazy
    
  16. 
    
  17. from .models import (
    
  18.     Article,
    
  19.     ArticleSelectOnSave,
    
  20.     ChildPrimaryKeyWithDefault,
    
  21.     FeaturedArticle,
    
  22.     PrimaryKeyWithDefault,
    
  23.     SelfRef,
    
  24. )
    
  25. 
    
  26. 
    
  27. class ModelInstanceCreationTests(TestCase):
    
  28.     def test_object_is_not_written_to_database_until_save_was_called(self):
    
  29.         a = Article(
    
  30.             id=None,
    
  31.             headline="Parrot programs in Python",
    
  32.             pub_date=datetime(2005, 7, 28),
    
  33.         )
    
  34.         self.assertIsNone(a.id)
    
  35.         self.assertEqual(Article.objects.count(), 0)
    
  36. 
    
  37.         # Save it into the database. You have to call save() explicitly.
    
  38.         a.save()
    
  39.         self.assertIsNotNone(a.id)
    
  40.         self.assertEqual(Article.objects.count(), 1)
    
  41. 
    
  42.     def test_can_initialize_model_instance_using_positional_arguments(self):
    
  43.         """
    
  44.         You can initialize a model instance using positional arguments,
    
  45.         which should match the field order as defined in the model.
    
  46.         """
    
  47.         a = Article(None, "Second article", datetime(2005, 7, 29))
    
  48.         a.save()
    
  49. 
    
  50.         self.assertEqual(a.headline, "Second article")
    
  51.         self.assertEqual(a.pub_date, datetime(2005, 7, 29, 0, 0))
    
  52. 
    
  53.     def test_can_create_instance_using_kwargs(self):
    
  54.         a = Article(
    
  55.             id=None,
    
  56.             headline="Third article",
    
  57.             pub_date=datetime(2005, 7, 30),
    
  58.         )
    
  59.         a.save()
    
  60.         self.assertEqual(a.headline, "Third article")
    
  61.         self.assertEqual(a.pub_date, datetime(2005, 7, 30, 0, 0))
    
  62. 
    
  63.     def test_autofields_generate_different_values_for_each_instance(self):
    
  64.         a1 = Article.objects.create(
    
  65.             headline="First", pub_date=datetime(2005, 7, 30, 0, 0)
    
  66.         )
    
  67.         a2 = Article.objects.create(
    
  68.             headline="First", pub_date=datetime(2005, 7, 30, 0, 0)
    
  69.         )
    
  70.         a3 = Article.objects.create(
    
  71.             headline="First", pub_date=datetime(2005, 7, 30, 0, 0)
    
  72.         )
    
  73.         self.assertNotEqual(a3.id, a1.id)
    
  74.         self.assertNotEqual(a3.id, a2.id)
    
  75. 
    
  76.     def test_can_mix_and_match_position_and_kwargs(self):
    
  77.         # You can also mix and match position and keyword arguments, but
    
  78.         # be sure not to duplicate field information.
    
  79.         a = Article(None, "Fourth article", pub_date=datetime(2005, 7, 31))
    
  80.         a.save()
    
  81.         self.assertEqual(a.headline, "Fourth article")
    
  82. 
    
  83.     def test_positional_and_keyword_args_for_the_same_field(self):
    
  84.         msg = "Article() got both positional and keyword arguments for field '%s'."
    
  85.         with self.assertRaisesMessage(TypeError, msg % "headline"):
    
  86.             Article(None, "Fifth article", headline="Other headline.")
    
  87.         with self.assertRaisesMessage(TypeError, msg % "headline"):
    
  88.             Article(None, "Sixth article", headline="")
    
  89.         with self.assertRaisesMessage(TypeError, msg % "pub_date"):
    
  90.             Article(None, "Seventh article", datetime(2021, 3, 1), pub_date=None)
    
  91. 
    
  92.     def test_cannot_create_instance_with_invalid_kwargs(self):
    
  93.         msg = "Article() got unexpected keyword arguments: 'foo'"
    
  94.         with self.assertRaisesMessage(TypeError, msg):
    
  95.             Article(
    
  96.                 id=None,
    
  97.                 headline="Some headline",
    
  98.                 pub_date=datetime(2005, 7, 31),
    
  99.                 foo="bar",
    
  100.             )
    
  101.         msg = "Article() got unexpected keyword arguments: 'foo', 'bar'"
    
  102.         with self.assertRaisesMessage(TypeError, msg):
    
  103.             Article(
    
  104.                 id=None,
    
  105.                 headline="Some headline",
    
  106.                 pub_date=datetime(2005, 7, 31),
    
  107.                 foo="bar",
    
  108.                 bar="baz",
    
  109.             )
    
  110. 
    
  111.     def test_can_leave_off_value_for_autofield_and_it_gets_value_on_save(self):
    
  112.         """
    
  113.         You can leave off the value for an AutoField when creating an
    
  114.         object, because it'll get filled in automatically when you save().
    
  115.         """
    
  116.         a = Article(headline="Article 5", pub_date=datetime(2005, 7, 31))
    
  117.         a.save()
    
  118.         self.assertEqual(a.headline, "Article 5")
    
  119.         self.assertIsNotNone(a.id)
    
  120. 
    
  121.     def test_leaving_off_a_field_with_default_set_the_default_will_be_saved(self):
    
  122.         a = Article(pub_date=datetime(2005, 7, 31))
    
  123.         a.save()
    
  124.         self.assertEqual(a.headline, "Default headline")
    
  125. 
    
  126.     def test_for_datetimefields_saves_as_much_precision_as_was_given(self):
    
  127.         """as much precision in *seconds*"""
    
  128.         a1 = Article(
    
  129.             headline="Article 7",
    
  130.             pub_date=datetime(2005, 7, 31, 12, 30),
    
  131.         )
    
  132.         a1.save()
    
  133.         self.assertEqual(
    
  134.             Article.objects.get(id__exact=a1.id).pub_date, datetime(2005, 7, 31, 12, 30)
    
  135.         )
    
  136. 
    
  137.         a2 = Article(
    
  138.             headline="Article 8",
    
  139.             pub_date=datetime(2005, 7, 31, 12, 30, 45),
    
  140.         )
    
  141.         a2.save()
    
  142.         self.assertEqual(
    
  143.             Article.objects.get(id__exact=a2.id).pub_date,
    
  144.             datetime(2005, 7, 31, 12, 30, 45),
    
  145.         )
    
  146. 
    
  147.     def test_saving_an_object_again_does_not_create_a_new_object(self):
    
  148.         a = Article(headline="original", pub_date=datetime(2014, 5, 16))
    
  149.         a.save()
    
  150.         current_id = a.id
    
  151. 
    
  152.         a.save()
    
  153.         self.assertEqual(a.id, current_id)
    
  154. 
    
  155.         a.headline = "Updated headline"
    
  156.         a.save()
    
  157.         self.assertEqual(a.id, current_id)
    
  158. 
    
  159.     def test_querysets_checking_for_membership(self):
    
  160.         headlines = ["Parrot programs in Python", "Second article", "Third article"]
    
  161.         some_pub_date = datetime(2014, 5, 16, 12, 1)
    
  162.         for headline in headlines:
    
  163.             Article(headline=headline, pub_date=some_pub_date).save()
    
  164.         a = Article(headline="Some headline", pub_date=some_pub_date)
    
  165.         a.save()
    
  166. 
    
  167.         # You can use 'in' to test for membership...
    
  168.         self.assertIn(a, Article.objects.all())
    
  169.         # ... but there will often be more efficient ways if that is all you need:
    
  170.         self.assertTrue(Article.objects.filter(id=a.id).exists())
    
  171. 
    
  172.     def test_save_primary_with_default(self):
    
  173.         # An UPDATE attempt is skipped when a primary key has default.
    
  174.         with self.assertNumQueries(1):
    
  175.             PrimaryKeyWithDefault().save()
    
  176. 
    
  177.     def test_save_parent_primary_with_default(self):
    
  178.         # An UPDATE attempt is skipped when an inherited primary key has
    
  179.         # default.
    
  180.         with self.assertNumQueries(2):
    
  181.             ChildPrimaryKeyWithDefault().save()
    
  182. 
    
  183. 
    
  184. class ModelTest(TestCase):
    
  185.     def test_objects_attribute_is_only_available_on_the_class_itself(self):
    
  186.         with self.assertRaisesMessage(
    
  187.             AttributeError, "Manager isn't accessible via Article instances"
    
  188.         ):
    
  189.             getattr(
    
  190.                 Article(),
    
  191.                 "objects",
    
  192.             )
    
  193.         self.assertFalse(hasattr(Article(), "objects"))
    
  194.         self.assertTrue(hasattr(Article, "objects"))
    
  195. 
    
  196.     def test_queryset_delete_removes_all_items_in_that_queryset(self):
    
  197.         headlines = ["An article", "Article One", "Amazing article", "Boring article"]
    
  198.         some_pub_date = datetime(2014, 5, 16, 12, 1)
    
  199.         for headline in headlines:
    
  200.             Article(headline=headline, pub_date=some_pub_date).save()
    
  201.         self.assertQuerysetEqual(
    
  202.             Article.objects.order_by("headline"),
    
  203.             sorted(headlines),
    
  204.             transform=lambda a: a.headline,
    
  205.         )
    
  206.         Article.objects.filter(headline__startswith="A").delete()
    
  207.         self.assertEqual(Article.objects.get().headline, "Boring article")
    
  208. 
    
  209.     def test_not_equal_and_equal_operators_behave_as_expected_on_instances(self):
    
  210.         some_pub_date = datetime(2014, 5, 16, 12, 1)
    
  211.         a1 = Article.objects.create(headline="First", pub_date=some_pub_date)
    
  212.         a2 = Article.objects.create(headline="Second", pub_date=some_pub_date)
    
  213.         self.assertNotEqual(a1, a2)
    
  214.         self.assertEqual(a1, Article.objects.get(id__exact=a1.id))
    
  215. 
    
  216.         self.assertNotEqual(
    
  217.             Article.objects.get(id__exact=a1.id), Article.objects.get(id__exact=a2.id)
    
  218.         )
    
  219. 
    
  220.     def test_microsecond_precision(self):
    
  221.         a9 = Article(
    
  222.             headline="Article 9",
    
  223.             pub_date=datetime(2005, 7, 31, 12, 30, 45, 180),
    
  224.         )
    
  225.         a9.save()
    
  226.         self.assertEqual(
    
  227.             Article.objects.get(pk=a9.pk).pub_date,
    
  228.             datetime(2005, 7, 31, 12, 30, 45, 180),
    
  229.         )
    
  230. 
    
  231.     def test_manually_specify_primary_key(self):
    
  232.         # You can manually specify the primary key when creating a new object.
    
  233.         a101 = Article(
    
  234.             id=101,
    
  235.             headline="Article 101",
    
  236.             pub_date=datetime(2005, 7, 31, 12, 30, 45),
    
  237.         )
    
  238.         a101.save()
    
  239.         a101 = Article.objects.get(pk=101)
    
  240.         self.assertEqual(a101.headline, "Article 101")
    
  241. 
    
  242.     def test_create_method(self):
    
  243.         # You can create saved objects in a single step
    
  244.         a10 = Article.objects.create(
    
  245.             headline="Article 10",
    
  246.             pub_date=datetime(2005, 7, 31, 12, 30, 45),
    
  247.         )
    
  248.         self.assertEqual(Article.objects.get(headline="Article 10"), a10)
    
  249. 
    
  250.     def test_year_lookup_edge_case(self):
    
  251.         # Edge-case test: A year lookup should retrieve all objects in
    
  252.         # the given year, including Jan. 1 and Dec. 31.
    
  253.         a11 = Article.objects.create(
    
  254.             headline="Article 11",
    
  255.             pub_date=datetime(2008, 1, 1),
    
  256.         )
    
  257.         a12 = Article.objects.create(
    
  258.             headline="Article 12",
    
  259.             pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
    
  260.         )
    
  261.         self.assertSequenceEqual(
    
  262.             Article.objects.filter(pub_date__year=2008),
    
  263.             [a11, a12],
    
  264.         )
    
  265. 
    
  266.     def test_unicode_data(self):
    
  267.         # Unicode data works, too.
    
  268.         a = Article(
    
  269.             headline="\u6797\u539f \u3081\u3050\u307f",
    
  270.             pub_date=datetime(2005, 7, 28),
    
  271.         )
    
  272.         a.save()
    
  273.         self.assertEqual(
    
  274.             Article.objects.get(pk=a.id).headline, "\u6797\u539f \u3081\u3050\u307f"
    
  275.         )
    
  276. 
    
  277.     def test_hash_function(self):
    
  278.         # Model instances have a hash function, so they can be used in sets
    
  279.         # or as dictionary keys. Two models compare as equal if their primary
    
  280.         # keys are equal.
    
  281.         a10 = Article.objects.create(
    
  282.             headline="Article 10",
    
  283.             pub_date=datetime(2005, 7, 31, 12, 30, 45),
    
  284.         )
    
  285.         a11 = Article.objects.create(
    
  286.             headline="Article 11",
    
  287.             pub_date=datetime(2008, 1, 1),
    
  288.         )
    
  289.         a12 = Article.objects.create(
    
  290.             headline="Article 12",
    
  291.             pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
    
  292.         )
    
  293. 
    
  294.         s = {a10, a11, a12}
    
  295.         self.assertIn(Article.objects.get(headline="Article 11"), s)
    
  296. 
    
  297.     def test_extra_method_select_argument_with_dashes_and_values(self):
    
  298.         # The 'select' argument to extra() supports names with dashes in
    
  299.         # them, as long as you use values().
    
  300.         Article.objects.bulk_create(
    
  301.             [
    
  302.                 Article(
    
  303.                     headline="Article 10", pub_date=datetime(2005, 7, 31, 12, 30, 45)
    
  304.                 ),
    
  305.                 Article(headline="Article 11", pub_date=datetime(2008, 1, 1)),
    
  306.                 Article(
    
  307.                     headline="Article 12",
    
  308.                     pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
    
  309.                 ),
    
  310.             ]
    
  311.         )
    
  312.         dicts = (
    
  313.             Article.objects.filter(pub_date__year=2008)
    
  314.             .extra(select={"dashed-value": "1"})
    
  315.             .values("headline", "dashed-value")
    
  316.         )
    
  317.         self.assertEqual(
    
  318.             [sorted(d.items()) for d in dicts],
    
  319.             [
    
  320.                 [("dashed-value", 1), ("headline", "Article 11")],
    
  321.                 [("dashed-value", 1), ("headline", "Article 12")],
    
  322.             ],
    
  323.         )
    
  324. 
    
  325.     def test_extra_method_select_argument_with_dashes(self):
    
  326.         # If you use 'select' with extra() and names containing dashes on a
    
  327.         # query that's *not* a values() query, those extra 'select' values
    
  328.         # will silently be ignored.
    
  329.         Article.objects.bulk_create(
    
  330.             [
    
  331.                 Article(
    
  332.                     headline="Article 10", pub_date=datetime(2005, 7, 31, 12, 30, 45)
    
  333.                 ),
    
  334.                 Article(headline="Article 11", pub_date=datetime(2008, 1, 1)),
    
  335.                 Article(
    
  336.                     headline="Article 12",
    
  337.                     pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
    
  338.                 ),
    
  339.             ]
    
  340.         )
    
  341.         articles = Article.objects.filter(pub_date__year=2008).extra(
    
  342.             select={"dashed-value": "1", "undashedvalue": "2"}
    
  343.         )
    
  344.         self.assertEqual(articles[0].undashedvalue, 2)
    
  345. 
    
  346.     def test_create_relation_with_gettext_lazy(self):
    
  347.         """
    
  348.         gettext_lazy objects work when saving model instances
    
  349.         through various methods. Refs #10498.
    
  350.         """
    
  351.         notlazy = "test"
    
  352.         lazy = gettext_lazy(notlazy)
    
  353.         Article.objects.create(headline=lazy, pub_date=datetime.now())
    
  354.         article = Article.objects.get()
    
  355.         self.assertEqual(article.headline, notlazy)
    
  356.         # test that assign + save works with Promise objects
    
  357.         article.headline = lazy
    
  358.         article.save()
    
  359.         self.assertEqual(article.headline, notlazy)
    
  360.         # test .update()
    
  361.         Article.objects.update(headline=lazy)
    
  362.         article = Article.objects.get()
    
  363.         self.assertEqual(article.headline, notlazy)
    
  364.         # still test bulk_create()
    
  365.         Article.objects.all().delete()
    
  366.         Article.objects.bulk_create([Article(headline=lazy, pub_date=datetime.now())])
    
  367.         article = Article.objects.get()
    
  368.         self.assertEqual(article.headline, notlazy)
    
  369. 
    
  370.     def test_emptyqs(self):
    
  371.         msg = "EmptyQuerySet can't be instantiated"
    
  372.         with self.assertRaisesMessage(TypeError, msg):
    
  373.             EmptyQuerySet()
    
  374.         self.assertIsInstance(Article.objects.none(), EmptyQuerySet)
    
  375.         self.assertNotIsInstance("", EmptyQuerySet)
    
  376. 
    
  377.     def test_emptyqs_values(self):
    
  378.         # test for #15959
    
  379.         Article.objects.create(headline="foo", pub_date=datetime.now())
    
  380.         with self.assertNumQueries(0):
    
  381.             qs = Article.objects.none().values_list("pk")
    
  382.             self.assertIsInstance(qs, EmptyQuerySet)
    
  383.             self.assertEqual(len(qs), 0)
    
  384. 
    
  385.     def test_emptyqs_customqs(self):
    
  386.         # A hacky test for custom QuerySet subclass - refs #17271
    
  387.         Article.objects.create(headline="foo", pub_date=datetime.now())
    
  388. 
    
  389.         class CustomQuerySet(models.QuerySet):
    
  390.             def do_something(self):
    
  391.                 return "did something"
    
  392. 
    
  393.         qs = Article.objects.all()
    
  394.         qs.__class__ = CustomQuerySet
    
  395.         qs = qs.none()
    
  396.         with self.assertNumQueries(0):
    
  397.             self.assertEqual(len(qs), 0)
    
  398.             self.assertIsInstance(qs, EmptyQuerySet)
    
  399.             self.assertEqual(qs.do_something(), "did something")
    
  400. 
    
  401.     def test_emptyqs_values_order(self):
    
  402.         # Tests for ticket #17712
    
  403.         Article.objects.create(headline="foo", pub_date=datetime.now())
    
  404.         with self.assertNumQueries(0):
    
  405.             self.assertEqual(
    
  406.                 len(Article.objects.none().values_list("id").order_by("id")), 0
    
  407.             )
    
  408.         with self.assertNumQueries(0):
    
  409.             self.assertEqual(
    
  410.                 len(
    
  411.                     Article.objects.none().filter(
    
  412.                         id__in=Article.objects.values_list("id", flat=True)
    
  413.                     )
    
  414.                 ),
    
  415.                 0,
    
  416.             )
    
  417. 
    
  418.     @skipUnlessDBFeature("can_distinct_on_fields")
    
  419.     def test_emptyqs_distinct(self):
    
  420.         # Tests for #19426
    
  421.         Article.objects.create(headline="foo", pub_date=datetime.now())
    
  422.         with self.assertNumQueries(0):
    
  423.             self.assertEqual(
    
  424.                 len(Article.objects.none().distinct("headline", "pub_date")), 0
    
  425.             )
    
  426. 
    
  427.     def test_ticket_20278(self):
    
  428.         sr = SelfRef.objects.create()
    
  429.         with self.assertRaises(ObjectDoesNotExist):
    
  430.             SelfRef.objects.get(selfref=sr)
    
  431. 
    
  432.     def test_eq(self):
    
  433.         self.assertEqual(Article(id=1), Article(id=1))
    
  434.         self.assertNotEqual(Article(id=1), object())
    
  435.         self.assertNotEqual(object(), Article(id=1))
    
  436.         a = Article()
    
  437.         self.assertEqual(a, a)
    
  438.         self.assertEqual(a, mock.ANY)
    
  439.         self.assertNotEqual(Article(), a)
    
  440. 
    
  441.     def test_hash(self):
    
  442.         # Value based on PK
    
  443.         self.assertEqual(hash(Article(id=1)), hash(1))
    
  444.         msg = "Model instances without primary key value are unhashable"
    
  445.         with self.assertRaisesMessage(TypeError, msg):
    
  446.             # No PK value -> unhashable (because save() would then change
    
  447.             # hash)
    
  448.             hash(Article())
    
  449. 
    
  450.     def test_missing_hash_not_inherited(self):
    
  451.         class NoHash(models.Model):
    
  452.             def __eq__(self, other):
    
  453.                 return super.__eq__(other)
    
  454. 
    
  455.         with self.assertRaisesMessage(TypeError, "unhashable type: 'NoHash'"):
    
  456.             hash(NoHash(id=1))
    
  457. 
    
  458.     def test_specified_parent_hash_inherited(self):
    
  459.         class ParentHash(models.Model):
    
  460.             def __eq__(self, other):
    
  461.                 return super.__eq__(other)
    
  462. 
    
  463.             __hash__ = models.Model.__hash__
    
  464. 
    
  465.         self.assertEqual(hash(ParentHash(id=1)), 1)
    
  466. 
    
  467.     def test_delete_and_access_field(self):
    
  468.         # Accessing a field after it's deleted from a model reloads its value.
    
  469.         pub_date = datetime.now()
    
  470.         article = Article.objects.create(headline="foo", pub_date=pub_date)
    
  471.         new_pub_date = article.pub_date + timedelta(days=10)
    
  472.         article.headline = "bar"
    
  473.         article.pub_date = new_pub_date
    
  474.         del article.headline
    
  475.         with self.assertNumQueries(1):
    
  476.             self.assertEqual(article.headline, "foo")
    
  477.         # Fields that weren't deleted aren't reloaded.
    
  478.         self.assertEqual(article.pub_date, new_pub_date)
    
  479. 
    
  480.     def test_multiple_objects_max_num_fetched(self):
    
  481.         max_results = MAX_GET_RESULTS - 1
    
  482.         Article.objects.bulk_create(
    
  483.             Article(headline="Area %s" % i, pub_date=datetime(2005, 7, 28))
    
  484.             for i in range(max_results)
    
  485.         )
    
  486.         self.assertRaisesMessage(
    
  487.             MultipleObjectsReturned,
    
  488.             "get() returned more than one Article -- it returned %d!" % max_results,
    
  489.             Article.objects.get,
    
  490.             headline__startswith="Area",
    
  491.         )
    
  492.         Article.objects.create(
    
  493.             headline="Area %s" % max_results, pub_date=datetime(2005, 7, 28)
    
  494.         )
    
  495.         self.assertRaisesMessage(
    
  496.             MultipleObjectsReturned,
    
  497.             "get() returned more than one Article -- it returned more than %d!"
    
  498.             % max_results,
    
  499.             Article.objects.get,
    
  500.             headline__startswith="Area",
    
  501.         )
    
  502. 
    
  503. 
    
  504. class ModelLookupTest(TestCase):
    
  505.     @classmethod
    
  506.     def setUpTestData(cls):
    
  507.         # Create an Article.
    
  508.         cls.a = Article(
    
  509.             id=None,
    
  510.             headline="Swallow programs in Python",
    
  511.             pub_date=datetime(2005, 7, 28),
    
  512.         )
    
  513.         # Save it into the database. You have to call save() explicitly.
    
  514.         cls.a.save()
    
  515. 
    
  516.     def test_all_lookup(self):
    
  517.         # Change values by changing the attributes, then calling save().
    
  518.         self.a.headline = "Parrot programs in Python"
    
  519.         self.a.save()
    
  520. 
    
  521.         # Article.objects.all() returns all the articles in the database.
    
  522.         self.assertSequenceEqual(Article.objects.all(), [self.a])
    
  523. 
    
  524.     def test_rich_lookup(self):
    
  525.         # Django provides a rich database lookup API.
    
  526.         self.assertEqual(Article.objects.get(id__exact=self.a.id), self.a)
    
  527.         self.assertEqual(Article.objects.get(headline__startswith="Swallow"), self.a)
    
  528.         self.assertEqual(Article.objects.get(pub_date__year=2005), self.a)
    
  529.         self.assertEqual(
    
  530.             Article.objects.get(pub_date__year=2005, pub_date__month=7), self.a
    
  531.         )
    
  532.         self.assertEqual(
    
  533.             Article.objects.get(
    
  534.                 pub_date__year=2005, pub_date__month=7, pub_date__day=28
    
  535.             ),
    
  536.             self.a,
    
  537.         )
    
  538.         self.assertEqual(Article.objects.get(pub_date__week_day=5), self.a)
    
  539. 
    
  540.     def test_equal_lookup(self):
    
  541.         # The "__exact" lookup type can be omitted, as a shortcut.
    
  542.         self.assertEqual(Article.objects.get(id=self.a.id), self.a)
    
  543.         self.assertEqual(
    
  544.             Article.objects.get(headline="Swallow programs in Python"), self.a
    
  545.         )
    
  546. 
    
  547.         self.assertSequenceEqual(
    
  548.             Article.objects.filter(pub_date__year=2005),
    
  549.             [self.a],
    
  550.         )
    
  551.         self.assertSequenceEqual(
    
  552.             Article.objects.filter(pub_date__year=2004),
    
  553.             [],
    
  554.         )
    
  555.         self.assertSequenceEqual(
    
  556.             Article.objects.filter(pub_date__year=2005, pub_date__month=7),
    
  557.             [self.a],
    
  558.         )
    
  559. 
    
  560.         self.assertSequenceEqual(
    
  561.             Article.objects.filter(pub_date__week_day=5),
    
  562.             [self.a],
    
  563.         )
    
  564.         self.assertSequenceEqual(
    
  565.             Article.objects.filter(pub_date__week_day=6),
    
  566.             [],
    
  567.         )
    
  568. 
    
  569.     def test_does_not_exist(self):
    
  570.         # Django raises an Article.DoesNotExist exception for get() if the
    
  571.         # parameters don't match any object.
    
  572.         with self.assertRaisesMessage(
    
  573.             ObjectDoesNotExist, "Article matching query does not exist."
    
  574.         ):
    
  575.             Article.objects.get(
    
  576.                 id__exact=2000,
    
  577.             )
    
  578.         # To avoid dict-ordering related errors check only one lookup
    
  579.         # in single assert.
    
  580.         with self.assertRaises(ObjectDoesNotExist):
    
  581.             Article.objects.get(pub_date__year=2005, pub_date__month=8)
    
  582.         with self.assertRaisesMessage(
    
  583.             ObjectDoesNotExist, "Article matching query does not exist."
    
  584.         ):
    
  585.             Article.objects.get(
    
  586.                 pub_date__week_day=6,
    
  587.             )
    
  588. 
    
  589.     def test_lookup_by_primary_key(self):
    
  590.         # Lookup by a primary key is the most common case, so Django
    
  591.         # provides a shortcut for primary-key exact lookups.
    
  592.         # The following is identical to articles.get(id=a.id).
    
  593.         self.assertEqual(Article.objects.get(pk=self.a.id), self.a)
    
  594. 
    
  595.         # pk can be used as a shortcut for the primary key name in any query.
    
  596.         self.assertSequenceEqual(Article.objects.filter(pk__in=[self.a.id]), [self.a])
    
  597. 
    
  598.         # Model instances of the same type and same ID are considered equal.
    
  599.         a = Article.objects.get(pk=self.a.id)
    
  600.         b = Article.objects.get(pk=self.a.id)
    
  601.         self.assertEqual(a, b)
    
  602. 
    
  603.     def test_too_many(self):
    
  604.         # Create a very similar object
    
  605.         a = Article(
    
  606.             id=None,
    
  607.             headline="Swallow bites Python",
    
  608.             pub_date=datetime(2005, 7, 28),
    
  609.         )
    
  610.         a.save()
    
  611. 
    
  612.         self.assertEqual(Article.objects.count(), 2)
    
  613. 
    
  614.         # Django raises an Article.MultipleObjectsReturned exception if the
    
  615.         # lookup matches more than one object
    
  616.         msg = "get() returned more than one Article -- it returned 2!"
    
  617.         with self.assertRaisesMessage(MultipleObjectsReturned, msg):
    
  618.             Article.objects.get(
    
  619.                 headline__startswith="Swallow",
    
  620.             )
    
  621.         with self.assertRaisesMessage(MultipleObjectsReturned, msg):
    
  622.             Article.objects.get(
    
  623.                 pub_date__year=2005,
    
  624.             )
    
  625.         with self.assertRaisesMessage(MultipleObjectsReturned, msg):
    
  626.             Article.objects.get(pub_date__year=2005, pub_date__month=7)
    
  627. 
    
  628. 
    
  629. class ConcurrentSaveTests(TransactionTestCase):
    
  630.     available_apps = ["basic"]
    
  631. 
    
  632.     @skipUnlessDBFeature("test_db_allows_multiple_connections")
    
  633.     def test_concurrent_delete_with_save(self):
    
  634.         """
    
  635.         Test fetching, deleting and finally saving an object - we should get
    
  636.         an insert in this case.
    
  637.         """
    
  638.         a = Article.objects.create(headline="foo", pub_date=datetime.now())
    
  639.         exceptions = []
    
  640. 
    
  641.         def deleter():
    
  642.             try:
    
  643.                 # Do not delete a directly - doing so alters its state.
    
  644.                 Article.objects.filter(pk=a.pk).delete()
    
  645.             except Exception as e:
    
  646.                 exceptions.append(e)
    
  647.             finally:
    
  648.                 connections[DEFAULT_DB_ALIAS].close()
    
  649. 
    
  650.         self.assertEqual(len(exceptions), 0)
    
  651.         t = threading.Thread(target=deleter)
    
  652.         t.start()
    
  653.         t.join()
    
  654.         a.save()
    
  655.         self.assertEqual(Article.objects.get(pk=a.pk).headline, "foo")
    
  656. 
    
  657. 
    
  658. class ManagerTest(SimpleTestCase):
    
  659.     QUERYSET_PROXY_METHODS = [
    
  660.         "none",
    
  661.         "count",
    
  662.         "dates",
    
  663.         "datetimes",
    
  664.         "distinct",
    
  665.         "extra",
    
  666.         "get",
    
  667.         "get_or_create",
    
  668.         "update_or_create",
    
  669.         "create",
    
  670.         "bulk_create",
    
  671.         "bulk_update",
    
  672.         "filter",
    
  673.         "aggregate",
    
  674.         "annotate",
    
  675.         "alias",
    
  676.         "complex_filter",
    
  677.         "exclude",
    
  678.         "in_bulk",
    
  679.         "iterator",
    
  680.         "earliest",
    
  681.         "latest",
    
  682.         "first",
    
  683.         "last",
    
  684.         "order_by",
    
  685.         "select_for_update",
    
  686.         "select_related",
    
  687.         "prefetch_related",
    
  688.         "values",
    
  689.         "values_list",
    
  690.         "update",
    
  691.         "reverse",
    
  692.         "defer",
    
  693.         "only",
    
  694.         "using",
    
  695.         "exists",
    
  696.         "contains",
    
  697.         "explain",
    
  698.         "_insert",
    
  699.         "_update",
    
  700.         "raw",
    
  701.         "union",
    
  702.         "intersection",
    
  703.         "difference",
    
  704.         "aaggregate",
    
  705.         "abulk_create",
    
  706.         "abulk_update",
    
  707.         "acontains",
    
  708.         "acount",
    
  709.         "acreate",
    
  710.         "aearliest",
    
  711.         "aexists",
    
  712.         "aexplain",
    
  713.         "afirst",
    
  714.         "aget",
    
  715.         "aget_or_create",
    
  716.         "ain_bulk",
    
  717.         "aiterator",
    
  718.         "alast",
    
  719.         "alatest",
    
  720.         "aupdate",
    
  721.         "aupdate_or_create",
    
  722.     ]
    
  723. 
    
  724.     def test_manager_methods(self):
    
  725.         """
    
  726.         This test ensures that the correct set of methods from `QuerySet`
    
  727.         are copied onto `Manager`.
    
  728. 
    
  729.         It's particularly useful to prevent accidentally leaking new methods
    
  730.         into `Manager`. New `QuerySet` methods that should also be copied onto
    
  731.         `Manager` will need to be added to `ManagerTest.QUERYSET_PROXY_METHODS`.
    
  732.         """
    
  733.         self.assertEqual(
    
  734.             sorted(BaseManager._get_queryset_methods(models.QuerySet)),
    
  735.             sorted(self.QUERYSET_PROXY_METHODS),
    
  736.         )
    
  737. 
    
  738. 
    
  739. class SelectOnSaveTests(TestCase):
    
  740.     def test_select_on_save(self):
    
  741.         a1 = Article.objects.create(pub_date=datetime.now())
    
  742.         with self.assertNumQueries(1):
    
  743.             a1.save()
    
  744.         asos = ArticleSelectOnSave.objects.create(pub_date=datetime.now())
    
  745.         with self.assertNumQueries(2):
    
  746.             asos.save()
    
  747.         with self.assertNumQueries(1):
    
  748.             asos.save(force_update=True)
    
  749.         Article.objects.all().delete()
    
  750.         with self.assertRaisesMessage(
    
  751.             DatabaseError, "Forced update did not affect any rows."
    
  752.         ):
    
  753.             with self.assertNumQueries(1):
    
  754.                 asos.save(force_update=True)
    
  755. 
    
  756.     def test_select_on_save_lying_update(self):
    
  757.         """
    
  758.         select_on_save works correctly if the database doesn't return correct
    
  759.         information about matched rows from UPDATE.
    
  760.         """
    
  761.         # Change the manager to not return "row matched" for update().
    
  762.         # We are going to change the Article's _base_manager class
    
  763.         # dynamically. This is a bit of a hack, but it seems hard to
    
  764.         # test this properly otherwise. Article's manager, because
    
  765.         # proxy models use their parent model's _base_manager.
    
  766. 
    
  767.         orig_class = Article._base_manager._queryset_class
    
  768. 
    
  769.         class FakeQuerySet(models.QuerySet):
    
  770.             # Make sure the _update method below is in fact called.
    
  771.             called = False
    
  772. 
    
  773.             def _update(self, *args, **kwargs):
    
  774.                 FakeQuerySet.called = True
    
  775.                 super()._update(*args, **kwargs)
    
  776.                 return 0
    
  777. 
    
  778.         try:
    
  779.             Article._base_manager._queryset_class = FakeQuerySet
    
  780.             asos = ArticleSelectOnSave.objects.create(pub_date=datetime.now())
    
  781.             with self.assertNumQueries(3):
    
  782.                 asos.save()
    
  783.                 self.assertTrue(FakeQuerySet.called)
    
  784.             # This is not wanted behavior, but this is how Django has always
    
  785.             # behaved for databases that do not return correct information
    
  786.             # about matched rows for UPDATE.
    
  787.             with self.assertRaisesMessage(
    
  788.                 DatabaseError, "Forced update did not affect any rows."
    
  789.             ):
    
  790.                 asos.save(force_update=True)
    
  791.             msg = (
    
  792.                 "An error occurred in the current transaction. You can't "
    
  793.                 "execute queries until the end of the 'atomic' block."
    
  794.             )
    
  795.             with self.assertRaisesMessage(DatabaseError, msg):
    
  796.                 asos.save(update_fields=["pub_date"])
    
  797.         finally:
    
  798.             Article._base_manager._queryset_class = orig_class
    
  799. 
    
  800. 
    
  801. class ModelRefreshTests(TestCase):
    
  802.     def test_refresh(self):
    
  803.         a = Article.objects.create(pub_date=datetime.now())
    
  804.         Article.objects.create(pub_date=datetime.now())
    
  805.         Article.objects.filter(pk=a.pk).update(headline="new headline")
    
  806.         with self.assertNumQueries(1):
    
  807.             a.refresh_from_db()
    
  808.             self.assertEqual(a.headline, "new headline")
    
  809. 
    
  810.         orig_pub_date = a.pub_date
    
  811.         new_pub_date = a.pub_date + timedelta(10)
    
  812.         Article.objects.update(headline="new headline 2", pub_date=new_pub_date)
    
  813.         with self.assertNumQueries(1):
    
  814.             a.refresh_from_db(fields=["headline"])
    
  815.             self.assertEqual(a.headline, "new headline 2")
    
  816.             self.assertEqual(a.pub_date, orig_pub_date)
    
  817.         with self.assertNumQueries(1):
    
  818.             a.refresh_from_db()
    
  819.             self.assertEqual(a.pub_date, new_pub_date)
    
  820. 
    
  821.     def test_unknown_kwarg(self):
    
  822.         s = SelfRef.objects.create()
    
  823.         msg = "refresh_from_db() got an unexpected keyword argument 'unknown_kwarg'"
    
  824.         with self.assertRaisesMessage(TypeError, msg):
    
  825.             s.refresh_from_db(unknown_kwarg=10)
    
  826. 
    
  827.     def test_lookup_in_fields(self):
    
  828.         s = SelfRef.objects.create()
    
  829.         msg = (
    
  830.             'Found "__" in fields argument. Relations and transforms are not allowed '
    
  831.             "in fields."
    
  832.         )
    
  833.         with self.assertRaisesMessage(ValueError, msg):
    
  834.             s.refresh_from_db(fields=["foo__bar"])
    
  835. 
    
  836.     def test_refresh_fk(self):
    
  837.         s1 = SelfRef.objects.create()
    
  838.         s2 = SelfRef.objects.create()
    
  839.         s3 = SelfRef.objects.create(selfref=s1)
    
  840.         s3_copy = SelfRef.objects.get(pk=s3.pk)
    
  841.         s3_copy.selfref.touched = True
    
  842.         s3.selfref = s2
    
  843.         s3.save()
    
  844.         with self.assertNumQueries(1):
    
  845.             s3_copy.refresh_from_db()
    
  846.         with self.assertNumQueries(1):
    
  847.             # The old related instance was thrown away (the selfref_id has
    
  848.             # changed). It needs to be reloaded on access, so one query
    
  849.             # executed.
    
  850.             self.assertFalse(hasattr(s3_copy.selfref, "touched"))
    
  851.             self.assertEqual(s3_copy.selfref, s2)
    
  852. 
    
  853.     def test_refresh_null_fk(self):
    
  854.         s1 = SelfRef.objects.create()
    
  855.         s2 = SelfRef.objects.create(selfref=s1)
    
  856.         s2.selfref = None
    
  857.         s2.refresh_from_db()
    
  858.         self.assertEqual(s2.selfref, s1)
    
  859. 
    
  860.     def test_refresh_unsaved(self):
    
  861.         pub_date = datetime.now()
    
  862.         a = Article.objects.create(pub_date=pub_date)
    
  863.         a2 = Article(id=a.pk)
    
  864.         with self.assertNumQueries(1):
    
  865.             a2.refresh_from_db()
    
  866.         self.assertEqual(a2.pub_date, pub_date)
    
  867.         self.assertEqual(a2._state.db, "default")
    
  868. 
    
  869.     def test_refresh_fk_on_delete_set_null(self):
    
  870.         a = Article.objects.create(
    
  871.             headline="Parrot programs in Python",
    
  872.             pub_date=datetime(2005, 7, 28),
    
  873.         )
    
  874.         s1 = SelfRef.objects.create(article=a)
    
  875.         a.delete()
    
  876.         s1.refresh_from_db()
    
  877.         self.assertIsNone(s1.article_id)
    
  878.         self.assertIsNone(s1.article)
    
  879. 
    
  880.     def test_refresh_no_fields(self):
    
  881.         a = Article.objects.create(pub_date=datetime.now())
    
  882.         with self.assertNumQueries(0):
    
  883.             a.refresh_from_db(fields=[])
    
  884. 
    
  885.     def test_refresh_clears_reverse_related(self):
    
  886.         """refresh_from_db() clear cached reverse relations."""
    
  887.         article = Article.objects.create(
    
  888.             headline="Parrot programs in Python",
    
  889.             pub_date=datetime(2005, 7, 28),
    
  890.         )
    
  891.         self.assertFalse(hasattr(article, "featured"))
    
  892.         FeaturedArticle.objects.create(article_id=article.pk)
    
  893.         article.refresh_from_db()
    
  894.         self.assertTrue(hasattr(article, "featured"))
    
  895. 
    
  896.     def test_refresh_clears_one_to_one_field(self):
    
  897.         article = Article.objects.create(
    
  898.             headline="Parrot programs in Python",
    
  899.             pub_date=datetime(2005, 7, 28),
    
  900.         )
    
  901.         featured = FeaturedArticle.objects.create(article_id=article.pk)
    
  902.         self.assertEqual(featured.article.headline, "Parrot programs in Python")
    
  903.         article.headline = "Parrot programs in Python 2.0"
    
  904.         article.save()
    
  905.         featured.refresh_from_db()
    
  906.         self.assertEqual(featured.article.headline, "Parrot programs in Python 2.0")
    
  907. 
    
  908.     def test_prefetched_cache_cleared(self):
    
  909.         a = Article.objects.create(pub_date=datetime(2005, 7, 28))
    
  910.         s = SelfRef.objects.create(article=a)
    
  911.         # refresh_from_db() without fields=[...]
    
  912.         a1_prefetched = Article.objects.prefetch_related("selfref_set").first()
    
  913.         self.assertCountEqual(a1_prefetched.selfref_set.all(), [s])
    
  914.         s.article = None
    
  915.         s.save()
    
  916.         # Relation is cleared and prefetch cache is stale.
    
  917.         self.assertCountEqual(a1_prefetched.selfref_set.all(), [s])
    
  918.         a1_prefetched.refresh_from_db()
    
  919.         # Cache was cleared and new results are available.
    
  920.         self.assertCountEqual(a1_prefetched.selfref_set.all(), [])
    
  921.         # refresh_from_db() with fields=[...]
    
  922.         a2_prefetched = Article.objects.prefetch_related("selfref_set").first()
    
  923.         self.assertCountEqual(a2_prefetched.selfref_set.all(), [])
    
  924.         s.article = a
    
  925.         s.save()
    
  926.         # Relation is added and prefetch cache is stale.
    
  927.         self.assertCountEqual(a2_prefetched.selfref_set.all(), [])
    
  928.         a2_prefetched.refresh_from_db(fields=["selfref_set"])
    
  929.         # Cache was cleared and new results are available.
    
  930.         self.assertCountEqual(a2_prefetched.selfref_set.all(), [s])