tests.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from __future__ import unicode_literals
  2. from django.db import models
  3. from django.test import TestCase
  4. from .models import (
  5. First, Third, Parent, Child, Category, Record, Relation, Car, Driver)
  6. class ManyToOneRegressionTests(TestCase):
  7. def test_object_creation(self):
  8. Third.objects.create(id='3', name='An example')
  9. parent = Parent(name='fred')
  10. parent.save()
  11. Child.objects.create(name='bam-bam', parent=parent)
  12. def test_fk_assignment_and_related_object_cache(self):
  13. # Tests of ForeignKey assignment and the related-object cache (see #6886).
  14. p = Parent.objects.create(name="Parent")
  15. c = Child.objects.create(name="Child", parent=p)
  16. # Look up the object again so that we get a "fresh" object.
  17. c = Child.objects.get(name="Child")
  18. p = c.parent
  19. # Accessing the related object again returns the exactly same object.
  20. self.assertTrue(c.parent is p)
  21. # But if we kill the cache, we get a new object.
  22. del c._parent_cache
  23. self.assertFalse(c.parent is p)
  24. # Assigning a new object results in that object getting cached immediately.
  25. p2 = Parent.objects.create(name="Parent 2")
  26. c.parent = p2
  27. self.assertTrue(c.parent is p2)
  28. # Assigning None succeeds if field is null=True.
  29. p.bestchild = None
  30. self.assertTrue(p.bestchild is None)
  31. # bestchild should still be None after saving.
  32. p.save()
  33. self.assertTrue(p.bestchild is None)
  34. # bestchild should still be None after fetching the object again.
  35. p = Parent.objects.get(name="Parent")
  36. self.assertTrue(p.bestchild is None)
  37. # Assigning None fails: Child.parent is null=False.
  38. self.assertRaises(ValueError, setattr, c, "parent", None)
  39. # You also can't assign an object of the wrong type here
  40. self.assertRaises(ValueError, setattr, c, "parent", First(id=1, second=1))
  41. # Nor can you explicitly assign None to Child.parent during object
  42. # creation (regression for #9649).
  43. self.assertRaises(ValueError, Child, name='xyzzy', parent=None)
  44. self.assertRaises(ValueError, Child.objects.create, name='xyzzy', parent=None)
  45. # Creation using keyword argument should cache the related object.
  46. p = Parent.objects.get(name="Parent")
  47. c = Child(parent=p)
  48. self.assertTrue(c.parent is p)
  49. # Creation using keyword argument and unsaved related instance (#8070).
  50. p = Parent()
  51. with self.assertRaisesMessage(ValueError,
  52. 'Cannot assign "%r": "%s" instance isn\'t saved in the database.'
  53. % (p, Child.parent.field.rel.to._meta.object_name)):
  54. Child(parent=p)
  55. # Creation using attname keyword argument and an id will cause the
  56. # related object to be fetched.
  57. p = Parent.objects.get(name="Parent")
  58. c = Child(parent_id=p.id)
  59. self.assertFalse(c.parent is p)
  60. self.assertEqual(c.parent, p)
  61. def test_multiple_foreignkeys(self):
  62. # Test of multiple ForeignKeys to the same model (bug #7125).
  63. c1 = Category.objects.create(name='First')
  64. c2 = Category.objects.create(name='Second')
  65. c3 = Category.objects.create(name='Third')
  66. r1 = Record.objects.create(category=c1)
  67. r2 = Record.objects.create(category=c1)
  68. r3 = Record.objects.create(category=c2)
  69. r4 = Record.objects.create(category=c2)
  70. r5 = Record.objects.create(category=c3)
  71. Relation.objects.create(left=r1, right=r2)
  72. Relation.objects.create(left=r3, right=r4)
  73. Relation.objects.create(left=r1, right=r3)
  74. Relation.objects.create(left=r5, right=r2)
  75. Relation.objects.create(left=r3, right=r2)
  76. q1 = Relation.objects.filter(left__category__name__in=['First'], right__category__name__in=['Second'])
  77. self.assertQuerysetEqual(q1, ["<Relation: First - Second>"])
  78. q2 = Category.objects.filter(record__left_set__right__category__name='Second').order_by('name')
  79. self.assertQuerysetEqual(q2, ["<Category: First>", "<Category: Second>"])
  80. p = Parent.objects.create(name="Parent")
  81. c = Child.objects.create(name="Child", parent=p)
  82. self.assertRaises(ValueError, Child.objects.create, name="Grandchild", parent=c)
  83. def test_fk_instantiation_outside_model(self):
  84. # Regression for #12190 -- Should be able to instantiate a FK outside
  85. # of a model, and interrogate its related field.
  86. cat = models.ForeignKey(Category)
  87. self.assertEqual('id', cat.rel.get_related_field().name)
  88. def test_relation_unsaved(self):
  89. # Test that the <field>_set manager does not join on Null value fields (#17541)
  90. Third.objects.create(name='Third 1')
  91. Third.objects.create(name='Third 2')
  92. th = Third(name="testing")
  93. # The object isn't saved an thus the relation field is null - we won't even
  94. # execute a query in this case.
  95. with self.assertNumQueries(0):
  96. self.assertEqual(th.child_set.count(), 0)
  97. th.save()
  98. # Now the model is saved, so we will need to execute an query.
  99. with self.assertNumQueries(1):
  100. self.assertEqual(th.child_set.count(), 0)
  101. def test_related_null_to_field(self):
  102. c1 = Car.objects.create()
  103. d1 = Driver.objects.create()
  104. self.assertIs(d1.car, None)
  105. with self.assertNumQueries(0):
  106. self.assertEqual(list(c1.drivers.all()), [])