123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934 |
- import datetime
- from copy import deepcopy
- from django.core.exceptions import FieldError, MultipleObjectsReturned
- from django.db import IntegrityError, models, transaction
- from django.test import TestCase
- from django.utils.deprecation import RemovedInDjango60Warning
- from django.utils.translation import gettext_lazy
- from .models import (
- Article,
- Category,
- Child,
- ChildNullableParent,
- ChildStringPrimaryKeyParent,
- City,
- Country,
- District,
- First,
- Parent,
- ParentStringPrimaryKey,
- Record,
- Relation,
- Reporter,
- School,
- Student,
- Third,
- ToFieldChild,
- )
- class ManyToOneTests(TestCase):
- @classmethod
- def setUpTestData(cls):
-
- cls.r = Reporter(first_name="John", last_name="Smith", email="john@example.com")
- cls.r.save()
- cls.r2 = Reporter(
- first_name="Paul", last_name="Jones", email="paul@example.com"
- )
- cls.r2.save()
-
- cls.a = Article(
- headline="This is a test",
- pub_date=datetime.date(2005, 7, 27),
- reporter=cls.r,
- )
- cls.a.save()
- def test_get(self):
-
- r = self.a.reporter
- self.assertEqual(r.id, self.r.id)
- self.assertEqual((r.first_name, self.r.last_name), ("John", "Smith"))
- def test_create(self):
-
-
- a3 = Article(
- headline="Third article",
- pub_date=datetime.date(2005, 7, 27),
- reporter_id=self.r.id,
- )
- a3.save()
- self.assertEqual(a3.reporter.id, self.r.id)
-
- a4 = Article(
- headline="Fourth article",
- pub_date=datetime.date(2005, 7, 27),
- reporter_id=str(self.r.id),
- )
- a4.save()
- self.assertEqual(repr(a4.reporter), "<Reporter: John Smith>")
- def test_add(self):
-
- new_article = self.r.article_set.create(
- headline="John's second story", pub_date=datetime.date(2005, 7, 29)
- )
- self.assertEqual(repr(new_article), "<Article: John's second story>")
- self.assertEqual(new_article.reporter.id, self.r.id)
-
- new_article2 = Article(
- headline="Paul's story", pub_date=datetime.date(2006, 1, 17)
- )
- msg = (
- "<Article: Paul's story> instance isn't saved. Use bulk=False or save the "
- "object first."
- )
- with self.assertRaisesMessage(ValueError, msg):
- self.r.article_set.add(new_article2)
- self.r.article_set.add(new_article2, bulk=False)
- self.assertEqual(new_article2.reporter.id, self.r.id)
- self.assertSequenceEqual(
- self.r.article_set.all(),
- [new_article, new_article2, self.a],
- )
-
- self.r2.article_set.add(new_article2)
- self.assertEqual(new_article2.reporter.id, self.r2.id)
- self.assertSequenceEqual(self.r2.article_set.all(), [new_article2])
-
- with transaction.atomic():
- with self.assertRaisesMessage(
- TypeError, "'Article' instance expected, got <Reporter:"
- ):
- self.r.article_set.add(self.r2)
- self.assertSequenceEqual(
- self.r.article_set.all(),
- [new_article, self.a],
- )
- def test_set(self):
- new_article = self.r.article_set.create(
- headline="John's second story", pub_date=datetime.date(2005, 7, 29)
- )
- new_article2 = self.r2.article_set.create(
- headline="Paul's story", pub_date=datetime.date(2006, 1, 17)
- )
-
- new_article2.reporter = self.r
- new_article2.save()
- self.assertEqual(repr(new_article2.reporter), "<Reporter: John Smith>")
- self.assertEqual(new_article2.reporter.id, self.r.id)
- self.assertSequenceEqual(
- self.r.article_set.all(),
- [new_article, new_article2, self.a],
- )
- self.assertSequenceEqual(self.r2.article_set.all(), [])
-
- self.r2.article_set.set([new_article, new_article2])
- self.assertSequenceEqual(self.r.article_set.all(), [self.a])
- self.assertSequenceEqual(
- self.r2.article_set.all(),
- [new_article, new_article2],
- )
-
-
- self.r.article_set.set([new_article])
- self.assertSequenceEqual(
- self.r.article_set.all(),
- [new_article, self.a],
- )
- self.assertSequenceEqual(self.r2.article_set.all(), [new_article2])
- def test_reverse_assignment_deprecation(self):
- msg = (
- "Direct assignment to the reverse side of a related set is "
- "prohibited. Use article_set.set() instead."
- )
- with self.assertRaisesMessage(TypeError, msg):
- self.r2.article_set = []
- def test_assign(self):
- new_article = self.r.article_set.create(
- headline="John's second story", pub_date=datetime.date(2005, 7, 29)
- )
- new_article2 = self.r2.article_set.create(
- headline="Paul's story", pub_date=datetime.date(2006, 1, 17)
- )
-
- new_article2.reporter = self.r
- new_article2.save()
- self.assertEqual(repr(new_article2.reporter), "<Reporter: John Smith>")
- self.assertEqual(new_article2.reporter.id, self.r.id)
- self.assertSequenceEqual(
- self.r.article_set.all(),
- [new_article, new_article2, self.a],
- )
- self.assertSequenceEqual(self.r2.article_set.all(), [])
-
- self.r2.article_set.set([new_article, new_article2])
- self.assertSequenceEqual(self.r.article_set.all(), [self.a])
- self.assertSequenceEqual(
- self.r2.article_set.all(),
- [new_article, new_article2],
- )
-
-
- self.r.article_set.set([new_article])
- self.assertSequenceEqual(
- self.r.article_set.all(),
- [new_article, self.a],
- )
- self.assertSequenceEqual(self.r2.article_set.all(), [new_article2])
-
- self.assertFalse(hasattr(self.r2.article_set, "remove"))
- self.assertFalse(hasattr(self.r2.article_set, "clear"))
- def test_assign_fk_id_value(self):
- parent = Parent.objects.create(name="jeff")
- child1 = Child.objects.create(name="frank", parent=parent)
- child2 = Child.objects.create(name="randy", parent=parent)
- parent.bestchild = child1
- parent.save()
- parent.bestchild_id = child2.pk
- parent.save()
- self.assertEqual(parent.bestchild_id, child2.pk)
- self.assertFalse(Parent.bestchild.is_cached(parent))
- self.assertEqual(parent.bestchild, child2)
- self.assertTrue(Parent.bestchild.is_cached(parent))
-
- parent.bestchild_id = child2.pk
- self.assertTrue(Parent.bestchild.is_cached(parent))
- def test_assign_fk_id_none(self):
- parent = Parent.objects.create(name="jeff")
- child = Child.objects.create(name="frank", parent=parent)
- parent.bestchild = child
- parent.save()
- parent.bestchild_id = None
- parent.save()
- self.assertIsNone(parent.bestchild_id)
- self.assertFalse(Parent.bestchild.is_cached(parent))
- self.assertIsNone(parent.bestchild)
- self.assertTrue(Parent.bestchild.is_cached(parent))
- def test_selects(self):
- new_article1 = self.r.article_set.create(
- headline="John's second story",
- pub_date=datetime.date(2005, 7, 29),
- )
- new_article2 = self.r2.article_set.create(
- headline="Paul's story",
- pub_date=datetime.date(2006, 1, 17),
- )
-
- self.assertSequenceEqual(
- self.r.article_set.all(),
- [new_article1, self.a],
- )
- self.assertSequenceEqual(
- self.r.article_set.filter(headline__startswith="This"), [self.a]
- )
- self.assertEqual(self.r.article_set.count(), 2)
- self.assertEqual(self.r2.article_set.count(), 1)
-
- self.assertSequenceEqual(Article.objects.filter(id__exact=self.a.id), [self.a])
- self.assertSequenceEqual(Article.objects.filter(pk=self.a.id), [self.a])
-
- self.assertSequenceEqual(
- Article.objects.filter(headline__startswith="This"), [self.a]
- )
-
-
-
-
- self.assertSequenceEqual(
- Article.objects.filter(reporter__first_name__exact="John"),
- [new_article1, self.a],
- )
-
- self.assertSequenceEqual(
- Article.objects.filter(reporter__first_name="John"),
- [new_article1, self.a],
- )
-
- self.assertSequenceEqual(
- Article.objects.filter(
- reporter__first_name__exact="John", reporter__last_name__exact="Smith"
- ),
- [new_article1, self.a],
- )
-
-
- queryset = Article.objects.filter(
- reporter__first_name__exact="John", reporter__last_name__exact="Smith"
- )
- self.assertNumQueries(1, list, queryset)
- self.assertEqual(
- queryset.query.get_compiler(queryset.db).as_sql()[0].count("INNER JOIN"), 1
- )
-
- self.assertSequenceEqual(
- Article.objects.filter(reporter__first_name__exact="John").extra(
- where=["many_to_one_reporter.last_name='Smith'"]
- ),
- [new_article1, self.a],
- )
-
-
- self.assertQuerySetEqual(
- (
- Article.objects.filter(reporter__first_name__exact="John").extra(
- where=["many_to_one_reporter.last_name='%s'" % "Smith"]
- )
- ),
- [new_article1, self.a],
- )
-
-
- self.assertSequenceEqual(
- Article.objects.filter(reporter__id__exact=self.r.id),
- [new_article1, self.a],
- )
- self.assertSequenceEqual(
- Article.objects.filter(reporter__pk=self.r.id),
- [new_article1, self.a],
- )
- self.assertSequenceEqual(
- Article.objects.filter(reporter=self.r.id),
- [new_article1, self.a],
- )
- self.assertSequenceEqual(
- Article.objects.filter(reporter=self.r),
- [new_article1, self.a],
- )
- self.assertSequenceEqual(
- Article.objects.filter(reporter__in=[self.r.id, self.r2.id]).distinct(),
- [new_article1, new_article2, self.a],
- )
- self.assertSequenceEqual(
- Article.objects.filter(reporter__in=[self.r, self.r2]).distinct(),
- [new_article1, new_article2, self.a],
- )
-
-
-
- self.assertSequenceEqual(
- Article.objects.filter(
- reporter__in=Reporter.objects.filter(first_name="John")
- .values("pk")
- .query
- ).distinct(),
- [new_article1, self.a],
- )
- def test_reverse_selects(self):
- a3 = Article.objects.create(
- headline="Third article",
- pub_date=datetime.date(2005, 7, 27),
- reporter_id=self.r.id,
- )
- Article.objects.create(
- headline="Fourth article",
- pub_date=datetime.date(2005, 7, 27),
- reporter_id=self.r.id,
- )
- john_smith = [self.r]
-
- self.assertSequenceEqual(
- Reporter.objects.filter(id__exact=self.r.id), john_smith
- )
- self.assertSequenceEqual(Reporter.objects.filter(pk=self.r.id), john_smith)
- self.assertSequenceEqual(
- Reporter.objects.filter(first_name__startswith="John"), john_smith
- )
-
- self.assertSequenceEqual(
- Reporter.objects.filter(article__id__exact=self.a.id), john_smith
- )
- self.assertSequenceEqual(
- Reporter.objects.filter(article__pk=self.a.id), john_smith
- )
- self.assertSequenceEqual(Reporter.objects.filter(article=self.a.id), john_smith)
- self.assertSequenceEqual(Reporter.objects.filter(article=self.a), john_smith)
- self.assertSequenceEqual(
- Reporter.objects.filter(article__in=[self.a.id, a3.id]).distinct(),
- john_smith,
- )
- self.assertSequenceEqual(
- Reporter.objects.filter(article__in=[self.a.id, a3]).distinct(), john_smith
- )
- self.assertSequenceEqual(
- Reporter.objects.filter(article__in=[self.a, a3]).distinct(), john_smith
- )
- self.assertCountEqual(
- Reporter.objects.filter(article__headline__startswith="T"),
- [self.r, self.r],
- )
- self.assertSequenceEqual(
- Reporter.objects.filter(article__headline__startswith="T").distinct(),
- john_smith,
- )
-
- self.assertEqual(
- Reporter.objects.filter(article__headline__startswith="T").count(), 2
- )
- self.assertEqual(
- Reporter.objects.filter(article__headline__startswith="T")
- .distinct()
- .count(),
- 1,
- )
-
- self.assertCountEqual(
- Reporter.objects.filter(article__reporter__first_name__startswith="John"),
- [self.r, self.r, self.r],
- )
- self.assertSequenceEqual(
- Reporter.objects.filter(
- article__reporter__first_name__startswith="John"
- ).distinct(),
- john_smith,
- )
- self.assertSequenceEqual(
- Reporter.objects.filter(article__reporter__exact=self.r).distinct(),
- john_smith,
- )
-
- self.assertSequenceEqual(
- Reporter.objects.filter(article__reporter=self.r).distinct(), john_smith
- )
-
-
-
- d = {"reporter__first_name": "John", "reporter__last_name": "Smith"}
- qs = (
- Article.objects.filter(
- reporter=self.r,
- )
- .distinct()
- .order_by()
- .values("reporter__first_name", "reporter__last_name")
- )
- self.assertEqual([d], list(qs))
- def test_select_related(self):
-
-
-
- r1 = Reporter.objects.create(
- first_name="Mike", last_name="Royko", email="royko@suntimes.com"
- )
- r2 = Reporter.objects.create(
- first_name="John", last_name="Kass", email="jkass@tribune.com"
- )
- Article.objects.create(
- headline="First", pub_date=datetime.date(1980, 4, 23), reporter=r1
- )
- Article.objects.create(
- headline="Second", pub_date=datetime.date(1980, 4, 23), reporter=r2
- )
- self.assertEqual(
- list(Article.objects.select_related().dates("pub_date", "day")),
- [datetime.date(1980, 4, 23), datetime.date(2005, 7, 27)],
- )
- self.assertEqual(
- list(Article.objects.select_related().dates("pub_date", "month")),
- [datetime.date(1980, 4, 1), datetime.date(2005, 7, 1)],
- )
- self.assertEqual(
- list(Article.objects.select_related().dates("pub_date", "year")),
- [datetime.date(1980, 1, 1), datetime.date(2005, 1, 1)],
- )
- def test_delete(self):
- new_article1 = self.r.article_set.create(
- headline="John's second story",
- pub_date=datetime.date(2005, 7, 29),
- )
- new_article2 = self.r2.article_set.create(
- headline="Paul's story",
- pub_date=datetime.date(2006, 1, 17),
- )
- new_article3 = Article.objects.create(
- headline="Third article",
- pub_date=datetime.date(2005, 7, 27),
- reporter_id=self.r.id,
- )
- new_article4 = Article.objects.create(
- headline="Fourth article",
- pub_date=datetime.date(2005, 7, 27),
- reporter_id=str(self.r.id),
- )
-
- self.assertSequenceEqual(
- Article.objects.all(),
- [new_article4, new_article1, new_article2, new_article3, self.a],
- )
- self.assertSequenceEqual(
- Reporter.objects.order_by("first_name"),
- [self.r, self.r2],
- )
- self.r2.delete()
- self.assertSequenceEqual(
- Article.objects.all(),
- [new_article4, new_article1, new_article3, self.a],
- )
- self.assertSequenceEqual(Reporter.objects.order_by("first_name"), [self.r])
-
- Reporter.objects.filter(article__headline__startswith="This").delete()
- self.assertSequenceEqual(Reporter.objects.all(), [])
- self.assertSequenceEqual(Article.objects.all(), [])
- def test_explicit_fk(self):
-
-
- a2, created = Article.objects.get_or_create(
- headline="John's second test",
- pub_date=datetime.date(2011, 5, 7),
- reporter_id=self.r.id,
- )
- self.assertTrue(created)
- self.assertEqual(a2.reporter.id, self.r.id)
-
- self.assertSequenceEqual(
- Article.objects.filter(reporter_id__exact=self.r.id),
- [a2, self.a],
- )
-
- a3 = Article.objects.create(
- headline="Paul's commentary",
- pub_date=datetime.date(2011, 5, 7),
- reporter_id=self.r2.id,
- )
- self.assertEqual(a3.reporter.id, self.r2.id)
-
- msg = "get() returned more than one Article -- it returned 2!"
- with self.assertRaisesMessage(MultipleObjectsReturned, msg):
- Article.objects.get(reporter_id=self.r.id)
- self.assertEqual(
- repr(a3),
- repr(
- Article.objects.get(
- reporter_id=self.r2.id, pub_date=datetime.date(2011, 5, 7)
- )
- ),
- )
- def test_deepcopy_and_circular_references(self):
-
-
- self.r.cached_query = Article.objects.filter(reporter=self.r)
- self.assertEqual(repr(deepcopy(self.r)), "<Reporter: John Smith>")
- def test_manager_class_caching(self):
- r1 = Reporter.objects.create(first_name="Mike")
- r2 = Reporter.objects.create(first_name="John")
-
- self.assertIs(r1.article_set.__class__, r1.article_set.__class__)
-
- self.assertIs(r1.article_set.__class__, r2.article_set.__class__)
- def test_create_relation_with_gettext_lazy(self):
- reporter = Reporter.objects.create(
- first_name="John", last_name="Smith", email="john.smith@example.com"
- )
- lazy = gettext_lazy("test")
- reporter.article_set.create(headline=lazy, pub_date=datetime.date(2011, 6, 10))
- notlazy = str(lazy)
- article = reporter.article_set.get()
- self.assertEqual(article.headline, notlazy)
- def test_values_list_exception(self):
- expected_message = (
- "Cannot resolve keyword 'notafield' into field. Choices are: %s"
- )
- reporter_fields = ", ".join(sorted(f.name for f in Reporter._meta.get_fields()))
- with self.assertRaisesMessage(FieldError, expected_message % reporter_fields):
- Article.objects.values_list("reporter__notafield")
- article_fields = ", ".join(
- ["EXTRA"] + sorted(f.name for f in Article._meta.get_fields())
- )
- with self.assertRaisesMessage(FieldError, expected_message % article_fields):
- Article.objects.extra(select={"EXTRA": "EXTRA_SELECT"}).values_list(
- "notafield"
- )
- def test_fk_assignment_and_related_object_cache(self):
-
- p = Parent.objects.create(name="Parent")
- c = Child.objects.create(name="Child", parent=p)
-
- c = Child.objects.get(name="Child")
- p = c.parent
-
- self.assertIs(c.parent, p)
-
- del c._state.fields_cache["parent"]
- self.assertIsNot(c.parent, p)
-
- p2 = Parent.objects.create(name="Parent 2")
- c.parent = p2
- self.assertIs(c.parent, p2)
-
- p.bestchild = None
- self.assertIsNone(p.bestchild)
-
- p.save()
- self.assertIsNone(p.bestchild)
-
- p = Parent.objects.get(name="Parent")
- self.assertIsNone(p.bestchild)
-
- setattr(c, "parent", None)
-
- msg = (
- 'Cannot assign "<First: First object (1)>": "Child.parent" must '
- 'be a "Parent" instance.'
- )
- with self.assertRaisesMessage(ValueError, msg):
- setattr(c, "parent", First(id=1, second=1))
-
- Child(name="xyzzy", parent=None)
-
-
- with self.assertRaises(IntegrityError), transaction.atomic():
- Child.objects.create(name="xyzzy", parent=None)
-
- p = Parent.objects.get(name="Parent")
- c = Child(parent=p)
- self.assertIs(c.parent, p)
-
- p = Parent()
- msg = (
- "save() prohibited to prevent data loss due to unsaved related object "
- "'parent'."
- )
- with self.assertRaisesMessage(ValueError, msg):
- Child.objects.create(parent=p)
- with self.assertRaisesMessage(ValueError, msg):
- ToFieldChild.objects.create(parent=p)
-
-
- p = Parent.objects.get(name="Parent")
- c = Child(parent_id=p.id)
- self.assertIsNot(c.parent, p)
- self.assertEqual(c.parent, p)
- def test_save_parent_after_assign(self):
- category = Category(name="cats")
- record = Record(category=category)
- category.save()
- record.save()
- category.name = "dogs"
- with self.assertNumQueries(0):
- self.assertEqual(category.id, record.category_id)
- self.assertEqual(category.name, record.category.name)
- def test_save_nullable_fk_after_parent(self):
- parent = Parent()
- child = ChildNullableParent(parent=parent)
- parent.save()
- child.save()
- child.refresh_from_db()
- self.assertEqual(child.parent, parent)
- def test_save_nullable_fk_after_parent_with_to_field(self):
- parent = Parent(name="jeff")
- child = ToFieldChild(parent=parent)
- parent.save()
- child.save()
- child.refresh_from_db()
- self.assertEqual(child.parent, parent)
- self.assertEqual(child.parent_id, parent.name)
- def test_save_fk_after_parent_with_non_numeric_pk_set_on_child(self):
- parent = ParentStringPrimaryKey()
- child = ChildStringPrimaryKeyParent(parent=parent)
- child.parent.name = "jeff"
- parent.save()
- child.save()
- child.refresh_from_db()
- self.assertEqual(child.parent, parent)
- self.assertEqual(child.parent_id, parent.name)
- def test_fk_to_bigautofield(self):
- ch = City.objects.create(name="Chicago")
- District.objects.create(city=ch, name="Far South")
- District.objects.create(city=ch, name="North")
- ny = City.objects.create(name="New York", id=2**33)
- District.objects.create(city=ny, name="Brooklyn")
- District.objects.create(city=ny, name="Manhattan")
- def test_fk_to_smallautofield(self):
- us = Country.objects.create(name="United States")
- City.objects.create(country=us, name="Chicago")
- City.objects.create(country=us, name="New York")
- uk = Country.objects.create(name="United Kingdom", id=2**11)
- City.objects.create(country=uk, name="London")
- City.objects.create(country=uk, name="Edinburgh")
- def test_multiple_foreignkeys(self):
-
- c1 = Category.objects.create(name="First")
- c2 = Category.objects.create(name="Second")
- c3 = Category.objects.create(name="Third")
- r1 = Record.objects.create(category=c1)
- r2 = Record.objects.create(category=c1)
- r3 = Record.objects.create(category=c2)
- r4 = Record.objects.create(category=c2)
- r5 = Record.objects.create(category=c3)
- Relation.objects.create(left=r1, right=r2)
- Relation.objects.create(left=r3, right=r4)
- rel = Relation.objects.create(left=r1, right=r3)
- Relation.objects.create(left=r5, right=r2)
- Relation.objects.create(left=r3, right=r2)
- q1 = Relation.objects.filter(
- left__category__name__in=["First"], right__category__name__in=["Second"]
- )
- self.assertSequenceEqual(q1, [rel])
- q2 = Category.objects.filter(
- record__left_set__right__category__name="Second"
- ).order_by("name")
- self.assertSequenceEqual(q2, [c1, c2])
- p = Parent.objects.create(name="Parent")
- c = Child.objects.create(name="Child", parent=p)
- msg = 'Cannot assign "%r": "Child.parent" must be a "Parent" instance.' % c
- with self.assertRaisesMessage(ValueError, msg):
- Child.objects.create(name="Grandchild", parent=c)
- def test_fk_instantiation_outside_model(self):
-
-
- cat = models.ForeignKey(Category, models.CASCADE)
- self.assertEqual("id", cat.remote_field.get_related_field().name)
- def test_relation_unsaved(self):
- Third.objects.create(name="Third 1")
- Third.objects.create(name="Third 2")
- th = Third(name="testing")
-
- msg = (
- "'Third' instance needs to have a primary key value before this "
- "relationship can be used."
- )
- with self.assertRaisesMessage(ValueError, msg):
- th.child_set.count()
-
- self.assertEqual(th.child_set.model, Third)
- th.save()
-
- with self.assertNumQueries(1):
- self.assertEqual(th.child_set.count(), 0)
- def test_related_object(self):
- public_school = School.objects.create(is_public=True)
- public_student = Student.objects.create(school=public_school)
- private_school = School.objects.create(is_public=False)
- private_student = Student.objects.create(school=private_school)
-
- self.assertSequenceEqual(School.objects.all(), [public_school])
- self.assertEqual(public_student.school, public_school)
-
-
-
- self.assertEqual(private_student.school, private_school)
- School._meta.base_manager_name = "objects"
- School._meta._expire_cache()
- try:
- private_student = Student.objects.get(pk=private_student.pk)
- with self.assertRaises(School.DoesNotExist):
- private_student.school
- finally:
- School._meta.base_manager_name = None
- School._meta._expire_cache()
- def test_hasattr_related_object(self):
-
-
-
- self.assertFalse(hasattr(Article(), "reporter"))
- def test_create_after_prefetch(self):
- c = City.objects.create(name="Musical City")
- d1 = District.objects.create(name="Ladida", city=c)
- city = City.objects.prefetch_related("districts").get(id=c.id)
- self.assertSequenceEqual(city.districts.all(), [d1])
- d2 = city.districts.create(name="Goa")
- self.assertSequenceEqual(city.districts.all(), [d1, d2])
- def test_clear_after_prefetch(self):
- c = City.objects.create(name="Musical City")
- d = District.objects.create(name="Ladida", city=c)
- city = City.objects.prefetch_related("districts").get(id=c.id)
- self.assertSequenceEqual(city.districts.all(), [d])
- city.districts.clear()
- self.assertSequenceEqual(city.districts.all(), [])
- def test_remove_after_prefetch(self):
- c = City.objects.create(name="Musical City")
- d = District.objects.create(name="Ladida", city=c)
- city = City.objects.prefetch_related("districts").get(id=c.id)
- self.assertSequenceEqual(city.districts.all(), [d])
- city.districts.remove(d)
- self.assertSequenceEqual(city.districts.all(), [])
- def test_add_after_prefetch(self):
- c = City.objects.create(name="Musical City")
- District.objects.create(name="Ladida", city=c)
- d2 = District.objects.create(name="Ladidu")
- city = City.objects.prefetch_related("districts").get(id=c.id)
- self.assertEqual(city.districts.count(), 1)
- city.districts.add(d2)
- self.assertEqual(city.districts.count(), 2)
- def test_set_after_prefetch(self):
- c = City.objects.create(name="Musical City")
- District.objects.create(name="Ladida", city=c)
- d2 = District.objects.create(name="Ladidu")
- city = City.objects.prefetch_related("districts").get(id=c.id)
- self.assertEqual(city.districts.count(), 1)
- city.districts.set([d2])
- self.assertSequenceEqual(city.districts.all(), [d2])
- def test_add_then_remove_after_prefetch(self):
- c = City.objects.create(name="Musical City")
- District.objects.create(name="Ladida", city=c)
- d2 = District.objects.create(name="Ladidu")
- city = City.objects.prefetch_related("districts").get(id=c.id)
- self.assertEqual(city.districts.count(), 1)
- city.districts.add(d2)
- self.assertEqual(city.districts.count(), 2)
- city.districts.remove(d2)
- self.assertEqual(city.districts.count(), 1)
- def test_cached_relation_invalidated_on_save(self):
- """
- Model.save() invalidates stale ForeignKey relations after a primary key
- assignment.
- """
- self.assertEqual(self.a.reporter, self.r)
- self.a.reporter_id = self.r2.pk
- self.a.save()
- self.assertEqual(self.a.reporter, self.r2)
- def test_cached_foreign_key_with_to_field_not_cleared_by_save(self):
- parent = Parent.objects.create(name="a")
- child = ToFieldChild.objects.create(parent=parent)
- with self.assertNumQueries(0):
- self.assertIs(child.parent, parent)
- def test_reverse_foreign_key_instance_to_field_caching(self):
- parent = Parent.objects.create(name="a")
- ToFieldChild.objects.create(parent=parent)
- child = parent.to_field_children.get()
- with self.assertNumQueries(0):
- self.assertIs(child.parent, parent)
- def test_add_remove_set_by_pk_raises(self):
- usa = Country.objects.create(name="United States")
- chicago = City.objects.create(name="Chicago")
- msg = "'City' instance expected, got %s" % chicago.pk
- with self.assertRaisesMessage(TypeError, msg):
- usa.cities.add(chicago.pk)
- with self.assertRaisesMessage(TypeError, msg):
- usa.cities.remove(chicago.pk)
- with self.assertRaisesMessage(TypeError, msg):
- usa.cities.set([chicago.pk])
- def test_get_prefetch_queryset_warning(self):
- City.objects.create(name="Chicago")
- cities = City.objects.all()
- msg = (
- "get_prefetch_queryset() is deprecated. Use get_prefetch_querysets() "
- "instead."
- )
- with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
- City.country.get_prefetch_queryset(cities)
- def test_get_prefetch_queryset_reverse_warning(self):
- usa = Country.objects.create(name="United States")
- City.objects.create(name="Chicago")
- countries = Country.objects.all()
- msg = (
- "get_prefetch_queryset() is deprecated. Use get_prefetch_querysets() "
- "instead."
- )
- with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
- usa.cities.get_prefetch_queryset(countries)
- def test_get_prefetch_querysets_invalid_querysets_length(self):
- City.objects.create(name="Chicago")
- cities = City.objects.all()
- msg = (
- "querysets argument of get_prefetch_querysets() should have a length of 1."
- )
- with self.assertRaisesMessage(ValueError, msg):
- City.country.get_prefetch_querysets(
- instances=cities,
- querysets=[Country.objects.all(), Country.objects.all()],
- )
- def test_get_prefetch_querysets_reverse_invalid_querysets_length(self):
- usa = Country.objects.create(name="United States")
- City.objects.create(name="Chicago")
- countries = Country.objects.all()
- msg = (
- "querysets argument of get_prefetch_querysets() should have a length of 1."
- )
- with self.assertRaisesMessage(ValueError, msg):
- usa.cities.get_prefetch_querysets(
- instances=countries,
- querysets=[City.objects.all(), City.objects.all()],
- )
|