tests.py 35 KB

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