1. from django.db.models import Q
    
  2. from django.test import TestCase
    
  3. 
    
  4. from .models import Issue, StringReferenceModel, User
    
  5. 
    
  6. 
    
  7. class RelatedObjectTests(TestCase):
    
  8.     def test_related_objects_have_name_attribute(self):
    
  9.         for field_name in ("test_issue_client", "test_issue_cc"):
    
  10.             obj = User._meta.get_field(field_name)
    
  11.             self.assertEqual(field_name, obj.field.related_query_name())
    
  12. 
    
  13.     def test_m2m_and_m2o(self):
    
  14.         r = User.objects.create(username="russell")
    
  15.         g = User.objects.create(username="gustav")
    
  16. 
    
  17.         i1 = Issue(num=1)
    
  18.         i1.client = r
    
  19.         i1.save()
    
  20. 
    
  21.         i2 = Issue(num=2)
    
  22.         i2.client = r
    
  23.         i2.save()
    
  24.         i2.cc.add(r)
    
  25. 
    
  26.         i3 = Issue(num=3)
    
  27.         i3.client = g
    
  28.         i3.save()
    
  29.         i3.cc.add(r)
    
  30. 
    
  31.         self.assertQuerysetEqual(
    
  32.             Issue.objects.filter(client=r.id),
    
  33.             [
    
  34.                 1,
    
  35.                 2,
    
  36.             ],
    
  37.             lambda i: i.num,
    
  38.         )
    
  39.         self.assertQuerysetEqual(
    
  40.             Issue.objects.filter(client=g.id),
    
  41.             [
    
  42.                 3,
    
  43.             ],
    
  44.             lambda i: i.num,
    
  45.         )
    
  46.         self.assertQuerysetEqual(Issue.objects.filter(cc__id__exact=g.id), [])
    
  47.         self.assertQuerysetEqual(
    
  48.             Issue.objects.filter(cc__id__exact=r.id),
    
  49.             [
    
  50.                 2,
    
  51.                 3,
    
  52.             ],
    
  53.             lambda i: i.num,
    
  54.         )
    
  55. 
    
  56.         # These queries combine results from the m2m and the m2o relationships.
    
  57.         # They're three ways of saying the same thing.
    
  58.         self.assertQuerysetEqual(
    
  59.             Issue.objects.filter(Q(cc__id__exact=r.id) | Q(client=r.id)),
    
  60.             [
    
  61.                 1,
    
  62.                 2,
    
  63.                 3,
    
  64.             ],
    
  65.             lambda i: i.num,
    
  66.         )
    
  67.         self.assertQuerysetEqual(
    
  68.             Issue.objects.filter(cc__id__exact=r.id)
    
  69.             | Issue.objects.filter(client=r.id),
    
  70.             [
    
  71.                 1,
    
  72.                 2,
    
  73.                 3,
    
  74.             ],
    
  75.             lambda i: i.num,
    
  76.         )
    
  77.         self.assertQuerysetEqual(
    
  78.             Issue.objects.filter(Q(client=r.id) | Q(cc__id__exact=r.id)),
    
  79.             [
    
  80.                 1,
    
  81.                 2,
    
  82.                 3,
    
  83.             ],
    
  84.             lambda i: i.num,
    
  85.         )
    
  86. 
    
  87. 
    
  88. class RelatedObjectUnicodeTests(TestCase):
    
  89.     def test_m2m_with_unicode_reference(self):
    
  90.         """
    
  91.         Regression test for #6045: references to other models can be
    
  92.         strings, providing they are directly convertible to ASCII.
    
  93.         """
    
  94.         m1 = StringReferenceModel.objects.create()
    
  95.         m2 = StringReferenceModel.objects.create()
    
  96.         m2.others.add(m1)  # used to cause an error (see ticket #6045)
    
  97.         m2.save()
    
  98.         list(m2.others.all())  # Force retrieval.