1. import unittest
    
  2. from datetime import date, datetime, time, timedelta
    
  3. from decimal import Decimal
    
  4. from operator import attrgetter, itemgetter
    
  5. from uuid import UUID
    
  6. 
    
  7. from django.core.exceptions import FieldError
    
  8. from django.db import connection
    
  9. from django.db.models import (
    
  10.     BinaryField,
    
  11.     BooleanField,
    
  12.     Case,
    
  13.     Count,
    
  14.     DecimalField,
    
  15.     F,
    
  16.     GenericIPAddressField,
    
  17.     IntegerField,
    
  18.     Max,
    
  19.     Min,
    
  20.     Q,
    
  21.     Sum,
    
  22.     TextField,
    
  23.     Value,
    
  24.     When,
    
  25. )
    
  26. from django.test import SimpleTestCase, TestCase
    
  27. 
    
  28. from .models import CaseTestModel, Client, FKCaseTestModel, O2OCaseTestModel
    
  29. 
    
  30. try:
    
  31.     from PIL import Image
    
  32. except ImportError:
    
  33.     Image = None
    
  34. 
    
  35. 
    
  36. class CaseExpressionTests(TestCase):
    
  37.     @classmethod
    
  38.     def setUpTestData(cls):
    
  39.         o = CaseTestModel.objects.create(integer=1, integer2=1, string="1")
    
  40.         O2OCaseTestModel.objects.create(o2o=o, integer=1)
    
  41.         FKCaseTestModel.objects.create(fk=o, integer=1)
    
  42. 
    
  43.         o = CaseTestModel.objects.create(integer=2, integer2=3, string="2")
    
  44.         O2OCaseTestModel.objects.create(o2o=o, integer=2)
    
  45.         FKCaseTestModel.objects.create(fk=o, integer=2)
    
  46.         FKCaseTestModel.objects.create(fk=o, integer=3)
    
  47. 
    
  48.         o = CaseTestModel.objects.create(integer=3, integer2=4, string="3")
    
  49.         O2OCaseTestModel.objects.create(o2o=o, integer=3)
    
  50.         FKCaseTestModel.objects.create(fk=o, integer=3)
    
  51.         FKCaseTestModel.objects.create(fk=o, integer=4)
    
  52. 
    
  53.         o = CaseTestModel.objects.create(integer=2, integer2=2, string="2")
    
  54.         O2OCaseTestModel.objects.create(o2o=o, integer=2)
    
  55.         FKCaseTestModel.objects.create(fk=o, integer=2)
    
  56.         FKCaseTestModel.objects.create(fk=o, integer=3)
    
  57. 
    
  58.         o = CaseTestModel.objects.create(integer=3, integer2=4, string="3")
    
  59.         O2OCaseTestModel.objects.create(o2o=o, integer=3)
    
  60.         FKCaseTestModel.objects.create(fk=o, integer=3)
    
  61.         FKCaseTestModel.objects.create(fk=o, integer=4)
    
  62. 
    
  63.         o = CaseTestModel.objects.create(integer=3, integer2=3, string="3")
    
  64.         O2OCaseTestModel.objects.create(o2o=o, integer=3)
    
  65.         FKCaseTestModel.objects.create(fk=o, integer=3)
    
  66.         FKCaseTestModel.objects.create(fk=o, integer=4)
    
  67. 
    
  68.         o = CaseTestModel.objects.create(integer=4, integer2=5, string="4")
    
  69.         O2OCaseTestModel.objects.create(o2o=o, integer=1)
    
  70.         FKCaseTestModel.objects.create(fk=o, integer=5)
    
  71. 
    
  72.         cls.group_by_fields = [
    
  73.             f.name
    
  74.             for f in CaseTestModel._meta.get_fields()
    
  75.             if not (f.is_relation and f.auto_created)
    
  76.             and (
    
  77.                 connection.features.allows_group_by_lob
    
  78.                 or not isinstance(f, (BinaryField, TextField))
    
  79.             )
    
  80.         ]
    
  81. 
    
  82.     def test_annotate(self):
    
  83.         self.assertQuerysetEqual(
    
  84.             CaseTestModel.objects.annotate(
    
  85.                 test=Case(
    
  86.                     When(integer=1, then=Value("one")),
    
  87.                     When(integer=2, then=Value("two")),
    
  88.                     default=Value("other"),
    
  89.                 )
    
  90.             ).order_by("pk"),
    
  91.             [
    
  92.                 (1, "one"),
    
  93.                 (2, "two"),
    
  94.                 (3, "other"),
    
  95.                 (2, "two"),
    
  96.                 (3, "other"),
    
  97.                 (3, "other"),
    
  98.                 (4, "other"),
    
  99.             ],
    
  100.             transform=attrgetter("integer", "test"),
    
  101.         )
    
  102. 
    
  103.     def test_annotate_without_default(self):
    
  104.         self.assertQuerysetEqual(
    
  105.             CaseTestModel.objects.annotate(
    
  106.                 test=Case(
    
  107.                     When(integer=1, then=1),
    
  108.                     When(integer=2, then=2),
    
  109.                 )
    
  110.             ).order_by("pk"),
    
  111.             [(1, 1), (2, 2), (3, None), (2, 2), (3, None), (3, None), (4, None)],
    
  112.             transform=attrgetter("integer", "test"),
    
  113.         )
    
  114. 
    
  115.     def test_annotate_with_expression_as_value(self):
    
  116.         self.assertQuerysetEqual(
    
  117.             CaseTestModel.objects.annotate(
    
  118.                 f_test=Case(
    
  119.                     When(integer=1, then=F("integer") + 1),
    
  120.                     When(integer=2, then=F("integer") + 3),
    
  121.                     default="integer",
    
  122.                 )
    
  123.             ).order_by("pk"),
    
  124.             [(1, 2), (2, 5), (3, 3), (2, 5), (3, 3), (3, 3), (4, 4)],
    
  125.             transform=attrgetter("integer", "f_test"),
    
  126.         )
    
  127. 
    
  128.     def test_annotate_with_expression_as_condition(self):
    
  129.         self.assertQuerysetEqual(
    
  130.             CaseTestModel.objects.annotate(
    
  131.                 f_test=Case(
    
  132.                     When(integer2=F("integer"), then=Value("equal")),
    
  133.                     When(integer2=F("integer") + 1, then=Value("+1")),
    
  134.                 )
    
  135.             ).order_by("pk"),
    
  136.             [
    
  137.                 (1, "equal"),
    
  138.                 (2, "+1"),
    
  139.                 (3, "+1"),
    
  140.                 (2, "equal"),
    
  141.                 (3, "+1"),
    
  142.                 (3, "equal"),
    
  143.                 (4, "+1"),
    
  144.             ],
    
  145.             transform=attrgetter("integer", "f_test"),
    
  146.         )
    
  147. 
    
  148.     def test_annotate_with_join_in_value(self):
    
  149.         self.assertQuerysetEqual(
    
  150.             CaseTestModel.objects.annotate(
    
  151.                 join_test=Case(
    
  152.                     When(integer=1, then=F("o2o_rel__integer") + 1),
    
  153.                     When(integer=2, then=F("o2o_rel__integer") + 3),
    
  154.                     default="o2o_rel__integer",
    
  155.                 )
    
  156.             ).order_by("pk"),
    
  157.             [(1, 2), (2, 5), (3, 3), (2, 5), (3, 3), (3, 3), (4, 1)],
    
  158.             transform=attrgetter("integer", "join_test"),
    
  159.         )
    
  160. 
    
  161.     def test_annotate_with_in_clause(self):
    
  162.         fk_rels = FKCaseTestModel.objects.filter(integer__in=[5])
    
  163.         self.assertQuerysetEqual(
    
  164.             CaseTestModel.objects.only("pk", "integer")
    
  165.             .annotate(
    
  166.                 in_test=Sum(
    
  167.                     Case(
    
  168.                         When(fk_rel__in=fk_rels, then=F("fk_rel__integer")),
    
  169.                         default=Value(0),
    
  170.                     )
    
  171.                 )
    
  172.             )
    
  173.             .order_by("pk"),
    
  174.             [(1, 0), (2, 0), (3, 0), (2, 0), (3, 0), (3, 0), (4, 5)],
    
  175.             transform=attrgetter("integer", "in_test"),
    
  176.         )
    
  177. 
    
  178.     def test_annotate_with_join_in_condition(self):
    
  179.         self.assertQuerysetEqual(
    
  180.             CaseTestModel.objects.annotate(
    
  181.                 join_test=Case(
    
  182.                     When(integer2=F("o2o_rel__integer"), then=Value("equal")),
    
  183.                     When(integer2=F("o2o_rel__integer") + 1, then=Value("+1")),
    
  184.                     default=Value("other"),
    
  185.                 )
    
  186.             ).order_by("pk"),
    
  187.             [
    
  188.                 (1, "equal"),
    
  189.                 (2, "+1"),
    
  190.                 (3, "+1"),
    
  191.                 (2, "equal"),
    
  192.                 (3, "+1"),
    
  193.                 (3, "equal"),
    
  194.                 (4, "other"),
    
  195.             ],
    
  196.             transform=attrgetter("integer", "join_test"),
    
  197.         )
    
  198. 
    
  199.     def test_annotate_with_join_in_predicate(self):
    
  200.         self.assertQuerysetEqual(
    
  201.             CaseTestModel.objects.annotate(
    
  202.                 join_test=Case(
    
  203.                     When(o2o_rel__integer=1, then=Value("one")),
    
  204.                     When(o2o_rel__integer=2, then=Value("two")),
    
  205.                     When(o2o_rel__integer=3, then=Value("three")),
    
  206.                     default=Value("other"),
    
  207.                 )
    
  208.             ).order_by("pk"),
    
  209.             [
    
  210.                 (1, "one"),
    
  211.                 (2, "two"),
    
  212.                 (3, "three"),
    
  213.                 (2, "two"),
    
  214.                 (3, "three"),
    
  215.                 (3, "three"),
    
  216.                 (4, "one"),
    
  217.             ],
    
  218.             transform=attrgetter("integer", "join_test"),
    
  219.         )
    
  220. 
    
  221.     def test_annotate_with_annotation_in_value(self):
    
  222.         self.assertQuerysetEqual(
    
  223.             CaseTestModel.objects.annotate(
    
  224.                 f_plus_1=F("integer") + 1,
    
  225.                 f_plus_3=F("integer") + 3,
    
  226.             )
    
  227.             .annotate(
    
  228.                 f_test=Case(
    
  229.                     When(integer=1, then="f_plus_1"),
    
  230.                     When(integer=2, then="f_plus_3"),
    
  231.                     default="integer",
    
  232.                 ),
    
  233.             )
    
  234.             .order_by("pk"),
    
  235.             [(1, 2), (2, 5), (3, 3), (2, 5), (3, 3), (3, 3), (4, 4)],
    
  236.             transform=attrgetter("integer", "f_test"),
    
  237.         )
    
  238. 
    
  239.     def test_annotate_with_annotation_in_condition(self):
    
  240.         self.assertQuerysetEqual(
    
  241.             CaseTestModel.objects.annotate(
    
  242.                 f_plus_1=F("integer") + 1,
    
  243.             )
    
  244.             .annotate(
    
  245.                 f_test=Case(
    
  246.                     When(integer2=F("integer"), then=Value("equal")),
    
  247.                     When(integer2=F("f_plus_1"), then=Value("+1")),
    
  248.                 ),
    
  249.             )
    
  250.             .order_by("pk"),
    
  251.             [
    
  252.                 (1, "equal"),
    
  253.                 (2, "+1"),
    
  254.                 (3, "+1"),
    
  255.                 (2, "equal"),
    
  256.                 (3, "+1"),
    
  257.                 (3, "equal"),
    
  258.                 (4, "+1"),
    
  259.             ],
    
  260.             transform=attrgetter("integer", "f_test"),
    
  261.         )
    
  262. 
    
  263.     def test_annotate_with_annotation_in_predicate(self):
    
  264.         self.assertQuerysetEqual(
    
  265.             CaseTestModel.objects.annotate(
    
  266.                 f_minus_2=F("integer") - 2,
    
  267.             )
    
  268.             .annotate(
    
  269.                 test=Case(
    
  270.                     When(f_minus_2=-1, then=Value("negative one")),
    
  271.                     When(f_minus_2=0, then=Value("zero")),
    
  272.                     When(f_minus_2=1, then=Value("one")),
    
  273.                     default=Value("other"),
    
  274.                 ),
    
  275.             )
    
  276.             .order_by("pk"),
    
  277.             [
    
  278.                 (1, "negative one"),
    
  279.                 (2, "zero"),
    
  280.                 (3, "one"),
    
  281.                 (2, "zero"),
    
  282.                 (3, "one"),
    
  283.                 (3, "one"),
    
  284.                 (4, "other"),
    
  285.             ],
    
  286.             transform=attrgetter("integer", "test"),
    
  287.         )
    
  288. 
    
  289.     def test_annotate_with_aggregation_in_value(self):
    
  290.         self.assertQuerysetEqual(
    
  291.             CaseTestModel.objects.values(*self.group_by_fields)
    
  292.             .annotate(
    
  293.                 min=Min("fk_rel__integer"),
    
  294.                 max=Max("fk_rel__integer"),
    
  295.             )
    
  296.             .annotate(
    
  297.                 test=Case(
    
  298.                     When(integer=2, then="min"),
    
  299.                     When(integer=3, then="max"),
    
  300.                 ),
    
  301.             )
    
  302.             .order_by("pk"),
    
  303.             [
    
  304.                 (1, None, 1, 1),
    
  305.                 (2, 2, 2, 3),
    
  306.                 (3, 4, 3, 4),
    
  307.                 (2, 2, 2, 3),
    
  308.                 (3, 4, 3, 4),
    
  309.                 (3, 4, 3, 4),
    
  310.                 (4, None, 5, 5),
    
  311.             ],
    
  312.             transform=itemgetter("integer", "test", "min", "max"),
    
  313.         )
    
  314. 
    
  315.     def test_annotate_with_aggregation_in_condition(self):
    
  316.         self.assertQuerysetEqual(
    
  317.             CaseTestModel.objects.values(*self.group_by_fields)
    
  318.             .annotate(
    
  319.                 min=Min("fk_rel__integer"),
    
  320.                 max=Max("fk_rel__integer"),
    
  321.             )
    
  322.             .annotate(
    
  323.                 test=Case(
    
  324.                     When(integer2=F("min"), then=Value("min")),
    
  325.                     When(integer2=F("max"), then=Value("max")),
    
  326.                 ),
    
  327.             )
    
  328.             .order_by("pk"),
    
  329.             [
    
  330.                 (1, 1, "min"),
    
  331.                 (2, 3, "max"),
    
  332.                 (3, 4, "max"),
    
  333.                 (2, 2, "min"),
    
  334.                 (3, 4, "max"),
    
  335.                 (3, 3, "min"),
    
  336.                 (4, 5, "min"),
    
  337.             ],
    
  338.             transform=itemgetter("integer", "integer2", "test"),
    
  339.         )
    
  340. 
    
  341.     def test_annotate_with_aggregation_in_predicate(self):
    
  342.         self.assertQuerysetEqual(
    
  343.             CaseTestModel.objects.values(*self.group_by_fields)
    
  344.             .annotate(
    
  345.                 max=Max("fk_rel__integer"),
    
  346.             )
    
  347.             .annotate(
    
  348.                 test=Case(
    
  349.                     When(max=3, then=Value("max = 3")),
    
  350.                     When(max=4, then=Value("max = 4")),
    
  351.                     default=Value(""),
    
  352.                 ),
    
  353.             )
    
  354.             .order_by("pk"),
    
  355.             [
    
  356.                 (1, 1, ""),
    
  357.                 (2, 3, "max = 3"),
    
  358.                 (3, 4, "max = 4"),
    
  359.                 (2, 3, "max = 3"),
    
  360.                 (3, 4, "max = 4"),
    
  361.                 (3, 4, "max = 4"),
    
  362.                 (4, 5, ""),
    
  363.             ],
    
  364.             transform=itemgetter("integer", "max", "test"),
    
  365.         )
    
  366. 
    
  367.     def test_annotate_exclude(self):
    
  368.         self.assertQuerysetEqual(
    
  369.             CaseTestModel.objects.annotate(
    
  370.                 test=Case(
    
  371.                     When(integer=1, then=Value("one")),
    
  372.                     When(integer=2, then=Value("two")),
    
  373.                     default=Value("other"),
    
  374.                 )
    
  375.             )
    
  376.             .exclude(test="other")
    
  377.             .order_by("pk"),
    
  378.             [(1, "one"), (2, "two"), (2, "two")],
    
  379.             transform=attrgetter("integer", "test"),
    
  380.         )
    
  381. 
    
  382.     def test_annotate_filter_decimal(self):
    
  383.         obj = CaseTestModel.objects.create(integer=0, decimal=Decimal("1"))
    
  384.         qs = CaseTestModel.objects.annotate(
    
  385.             x=Case(When(integer=0, then=F("decimal"))),
    
  386.             y=Case(When(integer=0, then=Value(Decimal("1")))),
    
  387.         )
    
  388.         self.assertSequenceEqual(qs.filter(Q(x=1) & Q(x=Decimal("1"))), [obj])
    
  389.         self.assertSequenceEqual(qs.filter(Q(y=1) & Q(y=Decimal("1"))), [obj])
    
  390. 
    
  391.     def test_annotate_values_not_in_order_by(self):
    
  392.         self.assertEqual(
    
  393.             list(
    
  394.                 CaseTestModel.objects.annotate(
    
  395.                     test=Case(
    
  396.                         When(integer=1, then=Value("one")),
    
  397.                         When(integer=2, then=Value("two")),
    
  398.                         When(integer=3, then=Value("three")),
    
  399.                         default=Value("other"),
    
  400.                     )
    
  401.                 )
    
  402.                 .order_by("test")
    
  403.                 .values_list("integer", flat=True)
    
  404.             ),
    
  405.             [1, 4, 3, 3, 3, 2, 2],
    
  406.         )
    
  407. 
    
  408.     def test_annotate_with_empty_when(self):
    
  409.         objects = CaseTestModel.objects.annotate(
    
  410.             selected=Case(
    
  411.                 When(pk__in=[], then=Value("selected")),
    
  412.                 default=Value("not selected"),
    
  413.             )
    
  414.         )
    
  415.         self.assertEqual(len(objects), CaseTestModel.objects.count())
    
  416.         self.assertTrue(all(obj.selected == "not selected" for obj in objects))
    
  417. 
    
  418.     def test_combined_expression(self):
    
  419.         self.assertQuerysetEqual(
    
  420.             CaseTestModel.objects.annotate(
    
  421.                 test=Case(
    
  422.                     When(integer=1, then=2),
    
  423.                     When(integer=2, then=1),
    
  424.                     default=3,
    
  425.                 )
    
  426.                 + 1,
    
  427.             ).order_by("pk"),
    
  428.             [(1, 3), (2, 2), (3, 4), (2, 2), (3, 4), (3, 4), (4, 4)],
    
  429.             transform=attrgetter("integer", "test"),
    
  430.         )
    
  431. 
    
  432.     def test_in_subquery(self):
    
  433.         self.assertQuerysetEqual(
    
  434.             CaseTestModel.objects.filter(
    
  435.                 pk__in=CaseTestModel.objects.annotate(
    
  436.                     test=Case(
    
  437.                         When(integer=F("integer2"), then="pk"),
    
  438.                         When(integer=4, then="pk"),
    
  439.                     ),
    
  440.                 ).values("test")
    
  441.             ).order_by("pk"),
    
  442.             [(1, 1), (2, 2), (3, 3), (4, 5)],
    
  443.             transform=attrgetter("integer", "integer2"),
    
  444.         )
    
  445. 
    
  446.     def test_condition_with_lookups(self):
    
  447.         qs = CaseTestModel.objects.annotate(
    
  448.             test=Case(
    
  449.                 When(Q(integer2=1), string="2", then=Value(False)),
    
  450.                 When(Q(integer2=1), string="1", then=Value(True)),
    
  451.                 default=Value(False),
    
  452.                 output_field=BooleanField(),
    
  453.             ),
    
  454.         )
    
  455.         self.assertIs(qs.get(integer=1).test, True)
    
  456. 
    
  457.     def test_case_reuse(self):
    
  458.         SOME_CASE = Case(
    
  459.             When(pk=0, then=Value("0")),
    
  460.             default=Value("1"),
    
  461.         )
    
  462.         self.assertQuerysetEqual(
    
  463.             CaseTestModel.objects.annotate(somecase=SOME_CASE).order_by("pk"),
    
  464.             CaseTestModel.objects.annotate(somecase=SOME_CASE)
    
  465.             .order_by("pk")
    
  466.             .values_list("pk", "somecase"),
    
  467.             lambda x: (x.pk, x.somecase),
    
  468.         )
    
  469. 
    
  470.     def test_aggregate(self):
    
  471.         self.assertEqual(
    
  472.             CaseTestModel.objects.aggregate(
    
  473.                 one=Sum(
    
  474.                     Case(
    
  475.                         When(integer=1, then=1),
    
  476.                     )
    
  477.                 ),
    
  478.                 two=Sum(
    
  479.                     Case(
    
  480.                         When(integer=2, then=1),
    
  481.                     )
    
  482.                 ),
    
  483.                 three=Sum(
    
  484.                     Case(
    
  485.                         When(integer=3, then=1),
    
  486.                     )
    
  487.                 ),
    
  488.                 four=Sum(
    
  489.                     Case(
    
  490.                         When(integer=4, then=1),
    
  491.                     )
    
  492.                 ),
    
  493.             ),
    
  494.             {"one": 1, "two": 2, "three": 3, "four": 1},
    
  495.         )
    
  496. 
    
  497.     def test_aggregate_with_expression_as_value(self):
    
  498.         self.assertEqual(
    
  499.             CaseTestModel.objects.aggregate(
    
  500.                 one=Sum(Case(When(integer=1, then="integer"))),
    
  501.                 two=Sum(Case(When(integer=2, then=F("integer") - 1))),
    
  502.                 three=Sum(Case(When(integer=3, then=F("integer") + 1))),
    
  503.             ),
    
  504.             {"one": 1, "two": 2, "three": 12},
    
  505.         )
    
  506. 
    
  507.     def test_aggregate_with_expression_as_condition(self):
    
  508.         self.assertEqual(
    
  509.             CaseTestModel.objects.aggregate(
    
  510.                 equal=Sum(
    
  511.                     Case(
    
  512.                         When(integer2=F("integer"), then=1),
    
  513.                     )
    
  514.                 ),
    
  515.                 plus_one=Sum(
    
  516.                     Case(
    
  517.                         When(integer2=F("integer") + 1, then=1),
    
  518.                     )
    
  519.                 ),
    
  520.             ),
    
  521.             {"equal": 3, "plus_one": 4},
    
  522.         )
    
  523. 
    
  524.     def test_filter(self):
    
  525.         self.assertQuerysetEqual(
    
  526.             CaseTestModel.objects.filter(
    
  527.                 integer2=Case(
    
  528.                     When(integer=2, then=3),
    
  529.                     When(integer=3, then=4),
    
  530.                     default=1,
    
  531.                 )
    
  532.             ).order_by("pk"),
    
  533.             [(1, 1), (2, 3), (3, 4), (3, 4)],
    
  534.             transform=attrgetter("integer", "integer2"),
    
  535.         )
    
  536. 
    
  537.     def test_filter_without_default(self):
    
  538.         self.assertQuerysetEqual(
    
  539.             CaseTestModel.objects.filter(
    
  540.                 integer2=Case(
    
  541.                     When(integer=2, then=3),
    
  542.                     When(integer=3, then=4),
    
  543.                 )
    
  544.             ).order_by("pk"),
    
  545.             [(2, 3), (3, 4), (3, 4)],
    
  546.             transform=attrgetter("integer", "integer2"),
    
  547.         )
    
  548. 
    
  549.     def test_filter_with_expression_as_value(self):
    
  550.         self.assertQuerysetEqual(
    
  551.             CaseTestModel.objects.filter(
    
  552.                 integer2=Case(
    
  553.                     When(integer=2, then=F("integer") + 1),
    
  554.                     When(integer=3, then=F("integer")),
    
  555.                     default="integer",
    
  556.                 )
    
  557.             ).order_by("pk"),
    
  558.             [(1, 1), (2, 3), (3, 3)],
    
  559.             transform=attrgetter("integer", "integer2"),
    
  560.         )
    
  561. 
    
  562.     def test_filter_with_expression_as_condition(self):
    
  563.         self.assertQuerysetEqual(
    
  564.             CaseTestModel.objects.filter(
    
  565.                 string=Case(
    
  566.                     When(integer2=F("integer"), then=Value("2")),
    
  567.                     When(integer2=F("integer") + 1, then=Value("3")),
    
  568.                 )
    
  569.             ).order_by("pk"),
    
  570.             [(3, 4, "3"), (2, 2, "2"), (3, 4, "3")],
    
  571.             transform=attrgetter("integer", "integer2", "string"),
    
  572.         )
    
  573. 
    
  574.     def test_filter_with_join_in_value(self):
    
  575.         self.assertQuerysetEqual(
    
  576.             CaseTestModel.objects.filter(
    
  577.                 integer2=Case(
    
  578.                     When(integer=2, then=F("o2o_rel__integer") + 1),
    
  579.                     When(integer=3, then=F("o2o_rel__integer")),
    
  580.                     default="o2o_rel__integer",
    
  581.                 )
    
  582.             ).order_by("pk"),
    
  583.             [(1, 1), (2, 3), (3, 3)],
    
  584.             transform=attrgetter("integer", "integer2"),
    
  585.         )
    
  586. 
    
  587.     def test_filter_with_join_in_condition(self):
    
  588.         self.assertQuerysetEqual(
    
  589.             CaseTestModel.objects.filter(
    
  590.                 integer=Case(
    
  591.                     When(integer2=F("o2o_rel__integer") + 1, then=2),
    
  592.                     When(integer2=F("o2o_rel__integer"), then=3),
    
  593.                 )
    
  594.             ).order_by("pk"),
    
  595.             [(2, 3), (3, 3)],
    
  596.             transform=attrgetter("integer", "integer2"),
    
  597.         )
    
  598. 
    
  599.     def test_filter_with_join_in_predicate(self):
    
  600.         self.assertQuerysetEqual(
    
  601.             CaseTestModel.objects.filter(
    
  602.                 integer2=Case(
    
  603.                     When(o2o_rel__integer=1, then=1),
    
  604.                     When(o2o_rel__integer=2, then=3),
    
  605.                     When(o2o_rel__integer=3, then=4),
    
  606.                 )
    
  607.             ).order_by("pk"),
    
  608.             [(1, 1), (2, 3), (3, 4), (3, 4)],
    
  609.             transform=attrgetter("integer", "integer2"),
    
  610.         )
    
  611. 
    
  612.     def test_filter_with_annotation_in_value(self):
    
  613.         self.assertQuerysetEqual(
    
  614.             CaseTestModel.objects.annotate(
    
  615.                 f=F("integer"),
    
  616.                 f_plus_1=F("integer") + 1,
    
  617.             )
    
  618.             .filter(
    
  619.                 integer2=Case(
    
  620.                     When(integer=2, then="f_plus_1"),
    
  621.                     When(integer=3, then="f"),
    
  622.                 ),
    
  623.             )
    
  624.             .order_by("pk"),
    
  625.             [(2, 3), (3, 3)],
    
  626.             transform=attrgetter("integer", "integer2"),
    
  627.         )
    
  628. 
    
  629.     def test_filter_with_annotation_in_condition(self):
    
  630.         self.assertQuerysetEqual(
    
  631.             CaseTestModel.objects.annotate(
    
  632.                 f_plus_1=F("integer") + 1,
    
  633.             )
    
  634.             .filter(
    
  635.                 integer=Case(
    
  636.                     When(integer2=F("integer"), then=2),
    
  637.                     When(integer2=F("f_plus_1"), then=3),
    
  638.                 ),
    
  639.             )
    
  640.             .order_by("pk"),
    
  641.             [(3, 4), (2, 2), (3, 4)],
    
  642.             transform=attrgetter("integer", "integer2"),
    
  643.         )
    
  644. 
    
  645.     def test_filter_with_annotation_in_predicate(self):
    
  646.         self.assertQuerysetEqual(
    
  647.             CaseTestModel.objects.annotate(
    
  648.                 f_plus_1=F("integer") + 1,
    
  649.             )
    
  650.             .filter(
    
  651.                 integer2=Case(
    
  652.                     When(f_plus_1=3, then=3),
    
  653.                     When(f_plus_1=4, then=4),
    
  654.                     default=1,
    
  655.                 ),
    
  656.             )
    
  657.             .order_by("pk"),
    
  658.             [(1, 1), (2, 3), (3, 4), (3, 4)],
    
  659.             transform=attrgetter("integer", "integer2"),
    
  660.         )
    
  661. 
    
  662.     def test_filter_with_aggregation_in_value(self):
    
  663.         self.assertQuerysetEqual(
    
  664.             CaseTestModel.objects.values(*self.group_by_fields)
    
  665.             .annotate(
    
  666.                 min=Min("fk_rel__integer"),
    
  667.                 max=Max("fk_rel__integer"),
    
  668.             )
    
  669.             .filter(
    
  670.                 integer2=Case(
    
  671.                     When(integer=2, then="min"),
    
  672.                     When(integer=3, then="max"),
    
  673.                 ),
    
  674.             )
    
  675.             .order_by("pk"),
    
  676.             [(3, 4, 3, 4), (2, 2, 2, 3), (3, 4, 3, 4)],
    
  677.             transform=itemgetter("integer", "integer2", "min", "max"),
    
  678.         )
    
  679. 
    
  680.     def test_filter_with_aggregation_in_condition(self):
    
  681.         self.assertQuerysetEqual(
    
  682.             CaseTestModel.objects.values(*self.group_by_fields)
    
  683.             .annotate(
    
  684.                 min=Min("fk_rel__integer"),
    
  685.                 max=Max("fk_rel__integer"),
    
  686.             )
    
  687.             .filter(
    
  688.                 integer=Case(
    
  689.                     When(integer2=F("min"), then=2),
    
  690.                     When(integer2=F("max"), then=3),
    
  691.                 ),
    
  692.             )
    
  693.             .order_by("pk"),
    
  694.             [(3, 4, 3, 4), (2, 2, 2, 3), (3, 4, 3, 4)],
    
  695.             transform=itemgetter("integer", "integer2", "min", "max"),
    
  696.         )
    
  697. 
    
  698.     def test_filter_with_aggregation_in_predicate(self):
    
  699.         self.assertQuerysetEqual(
    
  700.             CaseTestModel.objects.values(*self.group_by_fields)
    
  701.             .annotate(
    
  702.                 max=Max("fk_rel__integer"),
    
  703.             )
    
  704.             .filter(
    
  705.                 integer=Case(
    
  706.                     When(max=3, then=2),
    
  707.                     When(max=4, then=3),
    
  708.                 ),
    
  709.             )
    
  710.             .order_by("pk"),
    
  711.             [(2, 3, 3), (3, 4, 4), (2, 2, 3), (3, 4, 4), (3, 3, 4)],
    
  712.             transform=itemgetter("integer", "integer2", "max"),
    
  713.         )
    
  714. 
    
  715.     def test_update(self):
    
  716.         CaseTestModel.objects.update(
    
  717.             string=Case(
    
  718.                 When(integer=1, then=Value("one")),
    
  719.                 When(integer=2, then=Value("two")),
    
  720.                 default=Value("other"),
    
  721.             ),
    
  722.         )
    
  723.         self.assertQuerysetEqual(
    
  724.             CaseTestModel.objects.order_by("pk"),
    
  725.             [
    
  726.                 (1, "one"),
    
  727.                 (2, "two"),
    
  728.                 (3, "other"),
    
  729.                 (2, "two"),
    
  730.                 (3, "other"),
    
  731.                 (3, "other"),
    
  732.                 (4, "other"),
    
  733.             ],
    
  734.             transform=attrgetter("integer", "string"),
    
  735.         )
    
  736. 
    
  737.     def test_update_without_default(self):
    
  738.         CaseTestModel.objects.update(
    
  739.             integer2=Case(
    
  740.                 When(integer=1, then=1),
    
  741.                 When(integer=2, then=2),
    
  742.             ),
    
  743.         )
    
  744.         self.assertQuerysetEqual(
    
  745.             CaseTestModel.objects.order_by("pk"),
    
  746.             [(1, 1), (2, 2), (3, None), (2, 2), (3, None), (3, None), (4, None)],
    
  747.             transform=attrgetter("integer", "integer2"),
    
  748.         )
    
  749. 
    
  750.     def test_update_with_expression_as_value(self):
    
  751.         CaseTestModel.objects.update(
    
  752.             integer=Case(
    
  753.                 When(integer=1, then=F("integer") + 1),
    
  754.                 When(integer=2, then=F("integer") + 3),
    
  755.                 default="integer",
    
  756.             ),
    
  757.         )
    
  758.         self.assertQuerysetEqual(
    
  759.             CaseTestModel.objects.order_by("pk"),
    
  760.             [("1", 2), ("2", 5), ("3", 3), ("2", 5), ("3", 3), ("3", 3), ("4", 4)],
    
  761.             transform=attrgetter("string", "integer"),
    
  762.         )
    
  763. 
    
  764.     def test_update_with_expression_as_condition(self):
    
  765.         CaseTestModel.objects.update(
    
  766.             string=Case(
    
  767.                 When(integer2=F("integer"), then=Value("equal")),
    
  768.                 When(integer2=F("integer") + 1, then=Value("+1")),
    
  769.             ),
    
  770.         )
    
  771.         self.assertQuerysetEqual(
    
  772.             CaseTestModel.objects.order_by("pk"),
    
  773.             [
    
  774.                 (1, "equal"),
    
  775.                 (2, "+1"),
    
  776.                 (3, "+1"),
    
  777.                 (2, "equal"),
    
  778.                 (3, "+1"),
    
  779.                 (3, "equal"),
    
  780.                 (4, "+1"),
    
  781.             ],
    
  782.             transform=attrgetter("integer", "string"),
    
  783.         )
    
  784. 
    
  785.     def test_update_with_join_in_condition_raise_field_error(self):
    
  786.         with self.assertRaisesMessage(
    
  787.             FieldError, "Joined field references are not permitted in this query"
    
  788.         ):
    
  789.             CaseTestModel.objects.update(
    
  790.                 integer=Case(
    
  791.                     When(integer2=F("o2o_rel__integer") + 1, then=2),
    
  792.                     When(integer2=F("o2o_rel__integer"), then=3),
    
  793.                 ),
    
  794.             )
    
  795. 
    
  796.     def test_update_with_join_in_predicate_raise_field_error(self):
    
  797.         with self.assertRaisesMessage(
    
  798.             FieldError, "Joined field references are not permitted in this query"
    
  799.         ):
    
  800.             CaseTestModel.objects.update(
    
  801.                 string=Case(
    
  802.                     When(o2o_rel__integer=1, then=Value("one")),
    
  803.                     When(o2o_rel__integer=2, then=Value("two")),
    
  804.                     When(o2o_rel__integer=3, then=Value("three")),
    
  805.                     default=Value("other"),
    
  806.                 ),
    
  807.             )
    
  808. 
    
  809.     def test_update_big_integer(self):
    
  810.         CaseTestModel.objects.update(
    
  811.             big_integer=Case(
    
  812.                 When(integer=1, then=1),
    
  813.                 When(integer=2, then=2),
    
  814.             ),
    
  815.         )
    
  816.         self.assertQuerysetEqual(
    
  817.             CaseTestModel.objects.order_by("pk"),
    
  818.             [(1, 1), (2, 2), (3, None), (2, 2), (3, None), (3, None), (4, None)],
    
  819.             transform=attrgetter("integer", "big_integer"),
    
  820.         )
    
  821. 
    
  822.     def test_update_binary(self):
    
  823.         CaseTestModel.objects.update(
    
  824.             binary=Case(
    
  825.                 When(integer=1, then=b"one"),
    
  826.                 When(integer=2, then=b"two"),
    
  827.                 default=b"",
    
  828.             ),
    
  829.         )
    
  830.         self.assertQuerysetEqual(
    
  831.             CaseTestModel.objects.order_by("pk"),
    
  832.             [
    
  833.                 (1, b"one"),
    
  834.                 (2, b"two"),
    
  835.                 (3, b""),
    
  836.                 (2, b"two"),
    
  837.                 (3, b""),
    
  838.                 (3, b""),
    
  839.                 (4, b""),
    
  840.             ],
    
  841.             transform=lambda o: (o.integer, bytes(o.binary)),
    
  842.         )
    
  843. 
    
  844.     def test_update_boolean(self):
    
  845.         CaseTestModel.objects.update(
    
  846.             boolean=Case(
    
  847.                 When(integer=1, then=True),
    
  848.                 When(integer=2, then=True),
    
  849.                 default=False,
    
  850.             ),
    
  851.         )
    
  852.         self.assertQuerysetEqual(
    
  853.             CaseTestModel.objects.order_by("pk"),
    
  854.             [
    
  855.                 (1, True),
    
  856.                 (2, True),
    
  857.                 (3, False),
    
  858.                 (2, True),
    
  859.                 (3, False),
    
  860.                 (3, False),
    
  861.                 (4, False),
    
  862.             ],
    
  863.             transform=attrgetter("integer", "boolean"),
    
  864.         )
    
  865. 
    
  866.     def test_update_date(self):
    
  867.         CaseTestModel.objects.update(
    
  868.             date=Case(
    
  869.                 When(integer=1, then=date(2015, 1, 1)),
    
  870.                 When(integer=2, then=date(2015, 1, 2)),
    
  871.             ),
    
  872.         )
    
  873.         self.assertQuerysetEqual(
    
  874.             CaseTestModel.objects.order_by("pk"),
    
  875.             [
    
  876.                 (1, date(2015, 1, 1)),
    
  877.                 (2, date(2015, 1, 2)),
    
  878.                 (3, None),
    
  879.                 (2, date(2015, 1, 2)),
    
  880.                 (3, None),
    
  881.                 (3, None),
    
  882.                 (4, None),
    
  883.             ],
    
  884.             transform=attrgetter("integer", "date"),
    
  885.         )
    
  886. 
    
  887.     def test_update_date_time(self):
    
  888.         CaseTestModel.objects.update(
    
  889.             date_time=Case(
    
  890.                 When(integer=1, then=datetime(2015, 1, 1)),
    
  891.                 When(integer=2, then=datetime(2015, 1, 2)),
    
  892.             ),
    
  893.         )
    
  894.         self.assertQuerysetEqual(
    
  895.             CaseTestModel.objects.order_by("pk"),
    
  896.             [
    
  897.                 (1, datetime(2015, 1, 1)),
    
  898.                 (2, datetime(2015, 1, 2)),
    
  899.                 (3, None),
    
  900.                 (2, datetime(2015, 1, 2)),
    
  901.                 (3, None),
    
  902.                 (3, None),
    
  903.                 (4, None),
    
  904.             ],
    
  905.             transform=attrgetter("integer", "date_time"),
    
  906.         )
    
  907. 
    
  908.     def test_update_decimal(self):
    
  909.         CaseTestModel.objects.update(
    
  910.             decimal=Case(
    
  911.                 When(integer=1, then=Decimal("1.1")),
    
  912.                 When(
    
  913.                     integer=2, then=Value(Decimal("2.2"), output_field=DecimalField())
    
  914.                 ),
    
  915.             ),
    
  916.         )
    
  917.         self.assertQuerysetEqual(
    
  918.             CaseTestModel.objects.order_by("pk"),
    
  919.             [
    
  920.                 (1, Decimal("1.1")),
    
  921.                 (2, Decimal("2.2")),
    
  922.                 (3, None),
    
  923.                 (2, Decimal("2.2")),
    
  924.                 (3, None),
    
  925.                 (3, None),
    
  926.                 (4, None),
    
  927.             ],
    
  928.             transform=attrgetter("integer", "decimal"),
    
  929.         )
    
  930. 
    
  931.     def test_update_duration(self):
    
  932.         CaseTestModel.objects.update(
    
  933.             duration=Case(
    
  934.                 When(integer=1, then=timedelta(1)),
    
  935.                 When(integer=2, then=timedelta(2)),
    
  936.             ),
    
  937.         )
    
  938.         self.assertQuerysetEqual(
    
  939.             CaseTestModel.objects.order_by("pk"),
    
  940.             [
    
  941.                 (1, timedelta(1)),
    
  942.                 (2, timedelta(2)),
    
  943.                 (3, None),
    
  944.                 (2, timedelta(2)),
    
  945.                 (3, None),
    
  946.                 (3, None),
    
  947.                 (4, None),
    
  948.             ],
    
  949.             transform=attrgetter("integer", "duration"),
    
  950.         )
    
  951. 
    
  952.     def test_update_email(self):
    
  953.         CaseTestModel.objects.update(
    
  954.             email=Case(
    
  955.                 When(integer=1, then=Value("[email protected]")),
    
  956.                 When(integer=2, then=Value("[email protected]")),
    
  957.                 default=Value(""),
    
  958.             ),
    
  959.         )
    
  960.         self.assertQuerysetEqual(
    
  961.             CaseTestModel.objects.order_by("pk"),
    
  962.             [
    
  963.                 (1, "[email protected]"),
    
  964.                 (2, "[email protected]"),
    
  965.                 (3, ""),
    
  966.                 (2, "[email protected]"),
    
  967.                 (3, ""),
    
  968.                 (3, ""),
    
  969.                 (4, ""),
    
  970.             ],
    
  971.             transform=attrgetter("integer", "email"),
    
  972.         )
    
  973. 
    
  974.     def test_update_file(self):
    
  975.         CaseTestModel.objects.update(
    
  976.             file=Case(
    
  977.                 When(integer=1, then=Value("~/1")),
    
  978.                 When(integer=2, then=Value("~/2")),
    
  979.             ),
    
  980.         )
    
  981.         self.assertQuerysetEqual(
    
  982.             CaseTestModel.objects.order_by("pk"),
    
  983.             [(1, "~/1"), (2, "~/2"), (3, ""), (2, "~/2"), (3, ""), (3, ""), (4, "")],
    
  984.             transform=lambda o: (o.integer, str(o.file)),
    
  985.         )
    
  986. 
    
  987.     def test_update_file_path(self):
    
  988.         CaseTestModel.objects.update(
    
  989.             file_path=Case(
    
  990.                 When(integer=1, then=Value("~/1")),
    
  991.                 When(integer=2, then=Value("~/2")),
    
  992.                 default=Value(""),
    
  993.             ),
    
  994.         )
    
  995.         self.assertQuerysetEqual(
    
  996.             CaseTestModel.objects.order_by("pk"),
    
  997.             [(1, "~/1"), (2, "~/2"), (3, ""), (2, "~/2"), (3, ""), (3, ""), (4, "")],
    
  998.             transform=attrgetter("integer", "file_path"),
    
  999.         )
    
  1000. 
    
  1001.     def test_update_float(self):
    
  1002.         CaseTestModel.objects.update(
    
  1003.             float=Case(
    
  1004.                 When(integer=1, then=1.1),
    
  1005.                 When(integer=2, then=2.2),
    
  1006.             ),
    
  1007.         )
    
  1008.         self.assertQuerysetEqual(
    
  1009.             CaseTestModel.objects.order_by("pk"),
    
  1010.             [(1, 1.1), (2, 2.2), (3, None), (2, 2.2), (3, None), (3, None), (4, None)],
    
  1011.             transform=attrgetter("integer", "float"),
    
  1012.         )
    
  1013. 
    
  1014.     @unittest.skipUnless(Image, "Pillow not installed")
    
  1015.     def test_update_image(self):
    
  1016.         CaseTestModel.objects.update(
    
  1017.             image=Case(
    
  1018.                 When(integer=1, then=Value("~/1")),
    
  1019.                 When(integer=2, then=Value("~/2")),
    
  1020.             ),
    
  1021.         )
    
  1022.         self.assertQuerysetEqual(
    
  1023.             CaseTestModel.objects.order_by("pk"),
    
  1024.             [(1, "~/1"), (2, "~/2"), (3, ""), (2, "~/2"), (3, ""), (3, ""), (4, "")],
    
  1025.             transform=lambda o: (o.integer, str(o.image)),
    
  1026.         )
    
  1027. 
    
  1028.     def test_update_generic_ip_address(self):
    
  1029.         CaseTestModel.objects.update(
    
  1030.             generic_ip_address=Case(
    
  1031.                 When(integer=1, then=Value("1.1.1.1")),
    
  1032.                 When(integer=2, then=Value("2.2.2.2")),
    
  1033.                 output_field=GenericIPAddressField(),
    
  1034.             ),
    
  1035.         )
    
  1036.         self.assertQuerysetEqual(
    
  1037.             CaseTestModel.objects.order_by("pk"),
    
  1038.             [
    
  1039.                 (1, "1.1.1.1"),
    
  1040.                 (2, "2.2.2.2"),
    
  1041.                 (3, None),
    
  1042.                 (2, "2.2.2.2"),
    
  1043.                 (3, None),
    
  1044.                 (3, None),
    
  1045.                 (4, None),
    
  1046.             ],
    
  1047.             transform=attrgetter("integer", "generic_ip_address"),
    
  1048.         )
    
  1049. 
    
  1050.     def test_update_null_boolean(self):
    
  1051.         CaseTestModel.objects.update(
    
  1052.             null_boolean=Case(
    
  1053.                 When(integer=1, then=True),
    
  1054.                 When(integer=2, then=False),
    
  1055.             ),
    
  1056.         )
    
  1057.         self.assertQuerysetEqual(
    
  1058.             CaseTestModel.objects.order_by("pk"),
    
  1059.             [
    
  1060.                 (1, True),
    
  1061.                 (2, False),
    
  1062.                 (3, None),
    
  1063.                 (2, False),
    
  1064.                 (3, None),
    
  1065.                 (3, None),
    
  1066.                 (4, None),
    
  1067.             ],
    
  1068.             transform=attrgetter("integer", "null_boolean"),
    
  1069.         )
    
  1070. 
    
  1071.     def test_update_positive_big_integer(self):
    
  1072.         CaseTestModel.objects.update(
    
  1073.             positive_big_integer=Case(
    
  1074.                 When(integer=1, then=1),
    
  1075.                 When(integer=2, then=2),
    
  1076.             ),
    
  1077.         )
    
  1078.         self.assertQuerysetEqual(
    
  1079.             CaseTestModel.objects.order_by("pk"),
    
  1080.             [(1, 1), (2, 2), (3, None), (2, 2), (3, None), (3, None), (4, None)],
    
  1081.             transform=attrgetter("integer", "positive_big_integer"),
    
  1082.         )
    
  1083. 
    
  1084.     def test_update_positive_integer(self):
    
  1085.         CaseTestModel.objects.update(
    
  1086.             positive_integer=Case(
    
  1087.                 When(integer=1, then=1),
    
  1088.                 When(integer=2, then=2),
    
  1089.             ),
    
  1090.         )
    
  1091.         self.assertQuerysetEqual(
    
  1092.             CaseTestModel.objects.order_by("pk"),
    
  1093.             [(1, 1), (2, 2), (3, None), (2, 2), (3, None), (3, None), (4, None)],
    
  1094.             transform=attrgetter("integer", "positive_integer"),
    
  1095.         )
    
  1096. 
    
  1097.     def test_update_positive_small_integer(self):
    
  1098.         CaseTestModel.objects.update(
    
  1099.             positive_small_integer=Case(
    
  1100.                 When(integer=1, then=1),
    
  1101.                 When(integer=2, then=2),
    
  1102.             ),
    
  1103.         )
    
  1104.         self.assertQuerysetEqual(
    
  1105.             CaseTestModel.objects.order_by("pk"),
    
  1106.             [(1, 1), (2, 2), (3, None), (2, 2), (3, None), (3, None), (4, None)],
    
  1107.             transform=attrgetter("integer", "positive_small_integer"),
    
  1108.         )
    
  1109. 
    
  1110.     def test_update_slug(self):
    
  1111.         CaseTestModel.objects.update(
    
  1112.             slug=Case(
    
  1113.                 When(integer=1, then=Value("1")),
    
  1114.                 When(integer=2, then=Value("2")),
    
  1115.                 default=Value(""),
    
  1116.             ),
    
  1117.         )
    
  1118.         self.assertQuerysetEqual(
    
  1119.             CaseTestModel.objects.order_by("pk"),
    
  1120.             [(1, "1"), (2, "2"), (3, ""), (2, "2"), (3, ""), (3, ""), (4, "")],
    
  1121.             transform=attrgetter("integer", "slug"),
    
  1122.         )
    
  1123. 
    
  1124.     def test_update_small_integer(self):
    
  1125.         CaseTestModel.objects.update(
    
  1126.             small_integer=Case(
    
  1127.                 When(integer=1, then=1),
    
  1128.                 When(integer=2, then=2),
    
  1129.             ),
    
  1130.         )
    
  1131.         self.assertQuerysetEqual(
    
  1132.             CaseTestModel.objects.order_by("pk"),
    
  1133.             [(1, 1), (2, 2), (3, None), (2, 2), (3, None), (3, None), (4, None)],
    
  1134.             transform=attrgetter("integer", "small_integer"),
    
  1135.         )
    
  1136. 
    
  1137.     def test_update_string(self):
    
  1138.         CaseTestModel.objects.filter(string__in=["1", "2"]).update(
    
  1139.             string=Case(
    
  1140.                 When(integer=1, then=Value("1")),
    
  1141.                 When(integer=2, then=Value("2")),
    
  1142.             ),
    
  1143.         )
    
  1144.         self.assertQuerysetEqual(
    
  1145.             CaseTestModel.objects.filter(string__in=["1", "2"]).order_by("pk"),
    
  1146.             [(1, "1"), (2, "2"), (2, "2")],
    
  1147.             transform=attrgetter("integer", "string"),
    
  1148.         )
    
  1149. 
    
  1150.     def test_update_text(self):
    
  1151.         CaseTestModel.objects.update(
    
  1152.             text=Case(
    
  1153.                 When(integer=1, then=Value("1")),
    
  1154.                 When(integer=2, then=Value("2")),
    
  1155.                 default=Value(""),
    
  1156.             ),
    
  1157.         )
    
  1158.         self.assertQuerysetEqual(
    
  1159.             CaseTestModel.objects.order_by("pk"),
    
  1160.             [(1, "1"), (2, "2"), (3, ""), (2, "2"), (3, ""), (3, ""), (4, "")],
    
  1161.             transform=attrgetter("integer", "text"),
    
  1162.         )
    
  1163. 
    
  1164.     def test_update_time(self):
    
  1165.         CaseTestModel.objects.update(
    
  1166.             time=Case(
    
  1167.                 When(integer=1, then=time(1)),
    
  1168.                 When(integer=2, then=time(2)),
    
  1169.             ),
    
  1170.         )
    
  1171.         self.assertQuerysetEqual(
    
  1172.             CaseTestModel.objects.order_by("pk"),
    
  1173.             [
    
  1174.                 (1, time(1)),
    
  1175.                 (2, time(2)),
    
  1176.                 (3, None),
    
  1177.                 (2, time(2)),
    
  1178.                 (3, None),
    
  1179.                 (3, None),
    
  1180.                 (4, None),
    
  1181.             ],
    
  1182.             transform=attrgetter("integer", "time"),
    
  1183.         )
    
  1184. 
    
  1185.     def test_update_url(self):
    
  1186.         CaseTestModel.objects.update(
    
  1187.             url=Case(
    
  1188.                 When(integer=1, then=Value("http://1.example.com/")),
    
  1189.                 When(integer=2, then=Value("http://2.example.com/")),
    
  1190.                 default=Value(""),
    
  1191.             ),
    
  1192.         )
    
  1193.         self.assertQuerysetEqual(
    
  1194.             CaseTestModel.objects.order_by("pk"),
    
  1195.             [
    
  1196.                 (1, "http://1.example.com/"),
    
  1197.                 (2, "http://2.example.com/"),
    
  1198.                 (3, ""),
    
  1199.                 (2, "http://2.example.com/"),
    
  1200.                 (3, ""),
    
  1201.                 (3, ""),
    
  1202.                 (4, ""),
    
  1203.             ],
    
  1204.             transform=attrgetter("integer", "url"),
    
  1205.         )
    
  1206. 
    
  1207.     def test_update_uuid(self):
    
  1208.         CaseTestModel.objects.update(
    
  1209.             uuid=Case(
    
  1210.                 When(integer=1, then=UUID("11111111111111111111111111111111")),
    
  1211.                 When(integer=2, then=UUID("22222222222222222222222222222222")),
    
  1212.             ),
    
  1213.         )
    
  1214.         self.assertQuerysetEqual(
    
  1215.             CaseTestModel.objects.order_by("pk"),
    
  1216.             [
    
  1217.                 (1, UUID("11111111111111111111111111111111")),
    
  1218.                 (2, UUID("22222222222222222222222222222222")),
    
  1219.                 (3, None),
    
  1220.                 (2, UUID("22222222222222222222222222222222")),
    
  1221.                 (3, None),
    
  1222.                 (3, None),
    
  1223.                 (4, None),
    
  1224.             ],
    
  1225.             transform=attrgetter("integer", "uuid"),
    
  1226.         )
    
  1227. 
    
  1228.     def test_update_fk(self):
    
  1229.         obj1, obj2 = CaseTestModel.objects.all()[:2]
    
  1230. 
    
  1231.         CaseTestModel.objects.update(
    
  1232.             fk=Case(
    
  1233.                 When(integer=1, then=obj1.pk),
    
  1234.                 When(integer=2, then=obj2.pk),
    
  1235.             ),
    
  1236.         )
    
  1237.         self.assertQuerysetEqual(
    
  1238.             CaseTestModel.objects.order_by("pk"),
    
  1239.             [
    
  1240.                 (1, obj1.pk),
    
  1241.                 (2, obj2.pk),
    
  1242.                 (3, None),
    
  1243.                 (2, obj2.pk),
    
  1244.                 (3, None),
    
  1245.                 (3, None),
    
  1246.                 (4, None),
    
  1247.             ],
    
  1248.             transform=attrgetter("integer", "fk_id"),
    
  1249.         )
    
  1250. 
    
  1251.     def test_lookup_in_condition(self):
    
  1252.         self.assertQuerysetEqual(
    
  1253.             CaseTestModel.objects.annotate(
    
  1254.                 test=Case(
    
  1255.                     When(integer__lt=2, then=Value("less than 2")),
    
  1256.                     When(integer__gt=2, then=Value("greater than 2")),
    
  1257.                     default=Value("equal to 2"),
    
  1258.                 ),
    
  1259.             ).order_by("pk"),
    
  1260.             [
    
  1261.                 (1, "less than 2"),
    
  1262.                 (2, "equal to 2"),
    
  1263.                 (3, "greater than 2"),
    
  1264.                 (2, "equal to 2"),
    
  1265.                 (3, "greater than 2"),
    
  1266.                 (3, "greater than 2"),
    
  1267.                 (4, "greater than 2"),
    
  1268.             ],
    
  1269.             transform=attrgetter("integer", "test"),
    
  1270.         )
    
  1271. 
    
  1272.     def test_lookup_different_fields(self):
    
  1273.         self.assertQuerysetEqual(
    
  1274.             CaseTestModel.objects.annotate(
    
  1275.                 test=Case(
    
  1276.                     When(integer=2, integer2=3, then=Value("when")),
    
  1277.                     default=Value("default"),
    
  1278.                 ),
    
  1279.             ).order_by("pk"),
    
  1280.             [
    
  1281.                 (1, 1, "default"),
    
  1282.                 (2, 3, "when"),
    
  1283.                 (3, 4, "default"),
    
  1284.                 (2, 2, "default"),
    
  1285.                 (3, 4, "default"),
    
  1286.                 (3, 3, "default"),
    
  1287.                 (4, 5, "default"),
    
  1288.             ],
    
  1289.             transform=attrgetter("integer", "integer2", "test"),
    
  1290.         )
    
  1291. 
    
  1292.     def test_combined_q_object(self):
    
  1293.         self.assertQuerysetEqual(
    
  1294.             CaseTestModel.objects.annotate(
    
  1295.                 test=Case(
    
  1296.                     When(Q(integer=2) | Q(integer2=3), then=Value("when")),
    
  1297.                     default=Value("default"),
    
  1298.                 ),
    
  1299.             ).order_by("pk"),
    
  1300.             [
    
  1301.                 (1, 1, "default"),
    
  1302.                 (2, 3, "when"),
    
  1303.                 (3, 4, "default"),
    
  1304.                 (2, 2, "when"),
    
  1305.                 (3, 4, "default"),
    
  1306.                 (3, 3, "when"),
    
  1307.                 (4, 5, "default"),
    
  1308.             ],
    
  1309.             transform=attrgetter("integer", "integer2", "test"),
    
  1310.         )
    
  1311. 
    
  1312.     def test_order_by_conditional_implicit(self):
    
  1313.         self.assertQuerysetEqual(
    
  1314.             CaseTestModel.objects.filter(integer__lte=2)
    
  1315.             .annotate(
    
  1316.                 test=Case(
    
  1317.                     When(integer=1, then=2),
    
  1318.                     When(integer=2, then=1),
    
  1319.                     default=3,
    
  1320.                 )
    
  1321.             )
    
  1322.             .order_by("test", "pk"),
    
  1323.             [(2, 1), (2, 1), (1, 2)],
    
  1324.             transform=attrgetter("integer", "test"),
    
  1325.         )
    
  1326. 
    
  1327.     def test_order_by_conditional_explicit(self):
    
  1328.         self.assertQuerysetEqual(
    
  1329.             CaseTestModel.objects.filter(integer__lte=2)
    
  1330.             .annotate(
    
  1331.                 test=Case(
    
  1332.                     When(integer=1, then=2),
    
  1333.                     When(integer=2, then=1),
    
  1334.                     default=3,
    
  1335.                 )
    
  1336.             )
    
  1337.             .order_by(F("test").asc(), "pk"),
    
  1338.             [(2, 1), (2, 1), (1, 2)],
    
  1339.             transform=attrgetter("integer", "test"),
    
  1340.         )
    
  1341. 
    
  1342.     def test_join_promotion(self):
    
  1343.         o = CaseTestModel.objects.create(integer=1, integer2=1, string="1")
    
  1344.         # Testing that:
    
  1345.         # 1. There isn't any object on the remote side of the fk_rel
    
  1346.         #    relation. If the query used inner joins, then the join to fk_rel
    
  1347.         #    would remove o from the results. So, in effect we are testing that
    
  1348.         #    we are promoting the fk_rel join to a left outer join here.
    
  1349.         # 2. The default value of 3 is generated for the case expression.
    
  1350.         self.assertQuerysetEqual(
    
  1351.             CaseTestModel.objects.filter(pk=o.pk).annotate(
    
  1352.                 foo=Case(
    
  1353.                     When(fk_rel__pk=1, then=2),
    
  1354.                     default=3,
    
  1355.                 ),
    
  1356.             ),
    
  1357.             [(o, 3)],
    
  1358.             lambda x: (x, x.foo),
    
  1359.         )
    
  1360.         # Now 2 should be generated, as the fk_rel is null.
    
  1361.         self.assertQuerysetEqual(
    
  1362.             CaseTestModel.objects.filter(pk=o.pk).annotate(
    
  1363.                 foo=Case(
    
  1364.                     When(fk_rel__isnull=True, then=2),
    
  1365.                     default=3,
    
  1366.                 ),
    
  1367.             ),
    
  1368.             [(o, 2)],
    
  1369.             lambda x: (x, x.foo),
    
  1370.         )
    
  1371. 
    
  1372.     def test_join_promotion_multiple_annotations(self):
    
  1373.         o = CaseTestModel.objects.create(integer=1, integer2=1, string="1")
    
  1374.         # Testing that:
    
  1375.         # 1. There isn't any object on the remote side of the fk_rel
    
  1376.         #    relation. If the query used inner joins, then the join to fk_rel
    
  1377.         #    would remove o from the results. So, in effect we are testing that
    
  1378.         #    we are promoting the fk_rel join to a left outer join here.
    
  1379.         # 2. The default value of 3 is generated for the case expression.
    
  1380.         self.assertQuerysetEqual(
    
  1381.             CaseTestModel.objects.filter(pk=o.pk).annotate(
    
  1382.                 foo=Case(
    
  1383.                     When(fk_rel__pk=1, then=2),
    
  1384.                     default=3,
    
  1385.                 ),
    
  1386.                 bar=Case(
    
  1387.                     When(fk_rel__pk=1, then=4),
    
  1388.                     default=5,
    
  1389.                 ),
    
  1390.             ),
    
  1391.             [(o, 3, 5)],
    
  1392.             lambda x: (x, x.foo, x.bar),
    
  1393.         )
    
  1394.         # Now 2 should be generated, as the fk_rel is null.
    
  1395.         self.assertQuerysetEqual(
    
  1396.             CaseTestModel.objects.filter(pk=o.pk).annotate(
    
  1397.                 foo=Case(
    
  1398.                     When(fk_rel__isnull=True, then=2),
    
  1399.                     default=3,
    
  1400.                 ),
    
  1401.                 bar=Case(
    
  1402.                     When(fk_rel__isnull=True, then=4),
    
  1403.                     default=5,
    
  1404.                 ),
    
  1405.             ),
    
  1406.             [(o, 2, 4)],
    
  1407.             lambda x: (x, x.foo, x.bar),
    
  1408.         )
    
  1409. 
    
  1410.     def test_m2m_exclude(self):
    
  1411.         CaseTestModel.objects.create(integer=10, integer2=1, string="1")
    
  1412.         qs = (
    
  1413.             CaseTestModel.objects.values_list("id", "integer")
    
  1414.             .annotate(
    
  1415.                 cnt=Sum(
    
  1416.                     Case(When(~Q(fk_rel__integer=1), then=1), default=2),
    
  1417.                 ),
    
  1418.             )
    
  1419.             .order_by("integer")
    
  1420.         )
    
  1421.         # The first o has 2 as its fk_rel__integer=1, thus it hits the
    
  1422.         # default=2 case. The other ones have 2 as the result as they have 2
    
  1423.         # fk_rel objects, except for integer=4 and integer=10 (created above).
    
  1424.         # The integer=4 case has one integer, thus the result is 1, and
    
  1425.         # integer=10 doesn't have any and this too generates 1 (instead of 0)
    
  1426.         # as ~Q() also matches nulls.
    
  1427.         self.assertQuerysetEqual(
    
  1428.             qs,
    
  1429.             [(1, 2), (2, 2), (2, 2), (3, 2), (3, 2), (3, 2), (4, 1), (10, 1)],
    
  1430.             lambda x: x[1:],
    
  1431.         )
    
  1432. 
    
  1433.     def test_m2m_reuse(self):
    
  1434.         CaseTestModel.objects.create(integer=10, integer2=1, string="1")
    
  1435.         # Need to use values before annotate so that Oracle will not group
    
  1436.         # by fields it isn't capable of grouping by.
    
  1437.         qs = (
    
  1438.             CaseTestModel.objects.values_list("id", "integer")
    
  1439.             .annotate(
    
  1440.                 cnt=Sum(
    
  1441.                     Case(When(~Q(fk_rel__integer=1), then=1), default=2),
    
  1442.                 ),
    
  1443.             )
    
  1444.             .annotate(
    
  1445.                 cnt2=Sum(
    
  1446.                     Case(When(~Q(fk_rel__integer=1), then=1), default=2),
    
  1447.                 ),
    
  1448.             )
    
  1449.             .order_by("integer")
    
  1450.         )
    
  1451.         self.assertEqual(str(qs.query).count(" JOIN "), 1)
    
  1452.         self.assertQuerysetEqual(
    
  1453.             qs,
    
  1454.             [
    
  1455.                 (1, 2, 2),
    
  1456.                 (2, 2, 2),
    
  1457.                 (2, 2, 2),
    
  1458.                 (3, 2, 2),
    
  1459.                 (3, 2, 2),
    
  1460.                 (3, 2, 2),
    
  1461.                 (4, 1, 1),
    
  1462.                 (10, 1, 1),
    
  1463.             ],
    
  1464.             lambda x: x[1:],
    
  1465.         )
    
  1466. 
    
  1467.     def test_aggregation_empty_cases(self):
    
  1468.         tests = [
    
  1469.             # Empty cases and default.
    
  1470.             (Case(output_field=IntegerField()), None),
    
  1471.             # Empty cases and a constant default.
    
  1472.             (Case(default=Value("empty")), "empty"),
    
  1473.             # Empty cases and column in the default.
    
  1474.             (Case(default=F("url")), ""),
    
  1475.         ]
    
  1476.         for case, value in tests:
    
  1477.             with self.subTest(case=case):
    
  1478.                 self.assertQuerysetEqual(
    
  1479.                     CaseTestModel.objects.values("string")
    
  1480.                     .annotate(
    
  1481.                         case=case,
    
  1482.                         integer_sum=Sum("integer"),
    
  1483.                     )
    
  1484.                     .order_by("string"),
    
  1485.                     [
    
  1486.                         ("1", value, 1),
    
  1487.                         ("2", value, 4),
    
  1488.                         ("3", value, 9),
    
  1489.                         ("4", value, 4),
    
  1490.                     ],
    
  1491.                     transform=itemgetter("string", "case", "integer_sum"),
    
  1492.                 )
    
  1493. 
    
  1494. 
    
  1495. class CaseDocumentationExamples(TestCase):
    
  1496.     @classmethod
    
  1497.     def setUpTestData(cls):
    
  1498.         Client.objects.create(
    
  1499.             name="Jane Doe",
    
  1500.             account_type=Client.REGULAR,
    
  1501.             registered_on=date.today() - timedelta(days=36),
    
  1502.         )
    
  1503.         Client.objects.create(
    
  1504.             name="James Smith",
    
  1505.             account_type=Client.GOLD,
    
  1506.             registered_on=date.today() - timedelta(days=5),
    
  1507.         )
    
  1508.         Client.objects.create(
    
  1509.             name="Jack Black",
    
  1510.             account_type=Client.PLATINUM,
    
  1511.             registered_on=date.today() - timedelta(days=10 * 365),
    
  1512.         )
    
  1513. 
    
  1514.     def test_simple_example(self):
    
  1515.         self.assertQuerysetEqual(
    
  1516.             Client.objects.annotate(
    
  1517.                 discount=Case(
    
  1518.                     When(account_type=Client.GOLD, then=Value("5%")),
    
  1519.                     When(account_type=Client.PLATINUM, then=Value("10%")),
    
  1520.                     default=Value("0%"),
    
  1521.                 ),
    
  1522.             ).order_by("pk"),
    
  1523.             [("Jane Doe", "0%"), ("James Smith", "5%"), ("Jack Black", "10%")],
    
  1524.             transform=attrgetter("name", "discount"),
    
  1525.         )
    
  1526. 
    
  1527.     def test_lookup_example(self):
    
  1528.         a_month_ago = date.today() - timedelta(days=30)
    
  1529.         a_year_ago = date.today() - timedelta(days=365)
    
  1530.         self.assertQuerysetEqual(
    
  1531.             Client.objects.annotate(
    
  1532.                 discount=Case(
    
  1533.                     When(registered_on__lte=a_year_ago, then=Value("10%")),
    
  1534.                     When(registered_on__lte=a_month_ago, then=Value("5%")),
    
  1535.                     default=Value("0%"),
    
  1536.                 ),
    
  1537.             ).order_by("pk"),
    
  1538.             [("Jane Doe", "5%"), ("James Smith", "0%"), ("Jack Black", "10%")],
    
  1539.             transform=attrgetter("name", "discount"),
    
  1540.         )
    
  1541. 
    
  1542.     def test_conditional_update_example(self):
    
  1543.         a_month_ago = date.today() - timedelta(days=30)
    
  1544.         a_year_ago = date.today() - timedelta(days=365)
    
  1545.         Client.objects.update(
    
  1546.             account_type=Case(
    
  1547.                 When(registered_on__lte=a_year_ago, then=Value(Client.PLATINUM)),
    
  1548.                 When(registered_on__lte=a_month_ago, then=Value(Client.GOLD)),
    
  1549.                 default=Value(Client.REGULAR),
    
  1550.             ),
    
  1551.         )
    
  1552.         self.assertQuerysetEqual(
    
  1553.             Client.objects.order_by("pk"),
    
  1554.             [("Jane Doe", "G"), ("James Smith", "R"), ("Jack Black", "P")],
    
  1555.             transform=attrgetter("name", "account_type"),
    
  1556.         )
    
  1557. 
    
  1558.     def test_conditional_aggregation_example(self):
    
  1559.         Client.objects.create(
    
  1560.             name="Jean Grey",
    
  1561.             account_type=Client.REGULAR,
    
  1562.             registered_on=date.today(),
    
  1563.         )
    
  1564.         Client.objects.create(
    
  1565.             name="James Bond",
    
  1566.             account_type=Client.PLATINUM,
    
  1567.             registered_on=date.today(),
    
  1568.         )
    
  1569.         Client.objects.create(
    
  1570.             name="Jane Porter",
    
  1571.             account_type=Client.PLATINUM,
    
  1572.             registered_on=date.today(),
    
  1573.         )
    
  1574.         self.assertEqual(
    
  1575.             Client.objects.aggregate(
    
  1576.                 regular=Count("pk", filter=Q(account_type=Client.REGULAR)),
    
  1577.                 gold=Count("pk", filter=Q(account_type=Client.GOLD)),
    
  1578.                 platinum=Count("pk", filter=Q(account_type=Client.PLATINUM)),
    
  1579.             ),
    
  1580.             {"regular": 2, "gold": 1, "platinum": 3},
    
  1581.         )
    
  1582.         # This was the example before the filter argument was added.
    
  1583.         self.assertEqual(
    
  1584.             Client.objects.aggregate(
    
  1585.                 regular=Sum(
    
  1586.                     Case(
    
  1587.                         When(account_type=Client.REGULAR, then=1),
    
  1588.                     )
    
  1589.                 ),
    
  1590.                 gold=Sum(
    
  1591.                     Case(
    
  1592.                         When(account_type=Client.GOLD, then=1),
    
  1593.                     )
    
  1594.                 ),
    
  1595.                 platinum=Sum(
    
  1596.                     Case(
    
  1597.                         When(account_type=Client.PLATINUM, then=1),
    
  1598.                     )
    
  1599.                 ),
    
  1600.             ),
    
  1601.             {"regular": 2, "gold": 1, "platinum": 3},
    
  1602.         )
    
  1603. 
    
  1604.     def test_filter_example(self):
    
  1605.         a_month_ago = date.today() - timedelta(days=30)
    
  1606.         a_year_ago = date.today() - timedelta(days=365)
    
  1607.         self.assertQuerysetEqual(
    
  1608.             Client.objects.filter(
    
  1609.                 registered_on__lte=Case(
    
  1610.                     When(account_type=Client.GOLD, then=a_month_ago),
    
  1611.                     When(account_type=Client.PLATINUM, then=a_year_ago),
    
  1612.                 ),
    
  1613.             ),
    
  1614.             [("Jack Black", "P")],
    
  1615.             transform=attrgetter("name", "account_type"),
    
  1616.         )
    
  1617. 
    
  1618.     def test_hash(self):
    
  1619.         expression_1 = Case(
    
  1620.             When(account_type__in=[Client.REGULAR, Client.GOLD], then=1),
    
  1621.             default=2,
    
  1622.             output_field=IntegerField(),
    
  1623.         )
    
  1624.         expression_2 = Case(
    
  1625.             When(account_type__in=(Client.REGULAR, Client.GOLD), then=1),
    
  1626.             default=2,
    
  1627.             output_field=IntegerField(),
    
  1628.         )
    
  1629.         expression_3 = Case(
    
  1630.             When(account_type__in=[Client.REGULAR, Client.GOLD], then=1), default=2
    
  1631.         )
    
  1632.         expression_4 = Case(
    
  1633.             When(account_type__in=[Client.PLATINUM, Client.GOLD], then=2), default=1
    
  1634.         )
    
  1635.         self.assertEqual(hash(expression_1), hash(expression_2))
    
  1636.         self.assertNotEqual(hash(expression_2), hash(expression_3))
    
  1637.         self.assertNotEqual(hash(expression_1), hash(expression_4))
    
  1638.         self.assertNotEqual(hash(expression_3), hash(expression_4))
    
  1639. 
    
  1640. 
    
  1641. class CaseWhenTests(SimpleTestCase):
    
  1642.     def test_only_when_arguments(self):
    
  1643.         msg = "Positional arguments must all be When objects."
    
  1644.         with self.assertRaisesMessage(TypeError, msg):
    
  1645.             Case(When(Q(pk__in=[])), object())
    
  1646. 
    
  1647.     def test_invalid_when_constructor_args(self):
    
  1648.         msg = (
    
  1649.             "When() supports a Q object, a boolean expression, or lookups as "
    
  1650.             "a condition."
    
  1651.         )
    
  1652.         with self.assertRaisesMessage(TypeError, msg):
    
  1653.             When(condition=object())
    
  1654.         with self.assertRaisesMessage(TypeError, msg):
    
  1655.             When(condition=Value(1))
    
  1656.         with self.assertRaisesMessage(TypeError, msg):
    
  1657.             When(Value(1), string="1")
    
  1658.         with self.assertRaisesMessage(TypeError, msg):
    
  1659.             When()
    
  1660. 
    
  1661.     def test_empty_q_object(self):
    
  1662.         msg = "An empty Q() can't be used as a When() condition."
    
  1663.         with self.assertRaisesMessage(ValueError, msg):
    
  1664.             When(Q(), then=Value(True))