Skip to content

Commit

Permalink
Fixed #35111 -- Fixed compilation of DateField __in/__range rhs on SQ…
Browse files Browse the repository at this point in the history
…Lite and MySQL.

Also removed tests that ensured that adapt_(date)timefield backend
operations where able to deal with expressions when it's not the case
for any other adapt methods.
  • Loading branch information
charettes authored and felixxm committed Jan 16, 2024
1 parent 561f770 commit 0fcee16
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 40 deletions.
8 changes: 0 additions & 8 deletions django/db/backends/base/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,10 +562,6 @@ def adapt_datetimefield_value(self, value):
"""
if value is None:
return None
# Expression values are adapted by the database.
if hasattr(value, "resolve_expression"):
return value

return str(value)

def adapt_timefield_value(self, value):
Expand All @@ -575,10 +571,6 @@ def adapt_timefield_value(self, value):
"""
if value is None:
return None
# Expression values are adapted by the database.
if hasattr(value, "resolve_expression"):
return value

if timezone.is_aware(value):
raise ValueError("Django does not support timezone-aware times.")
return str(value)
Expand Down
8 changes: 0 additions & 8 deletions django/db/backends/oracle/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,10 +590,6 @@ def adapt_datetimefield_value(self, value):
if value is None:
return None

# Expression values are adapted by the database.
if hasattr(value, "resolve_expression"):
return value

# oracledb doesn't support tz-aware datetimes
if timezone.is_aware(value):
if settings.USE_TZ:
Expand All @@ -610,10 +606,6 @@ def adapt_timefield_value(self, value):
if value is None:
return None

# Expression values are adapted by the database.
if hasattr(value, "resolve_expression"):
return value

if isinstance(value, str):
return datetime.datetime.strptime(value, "%H:%M:%S")

Expand Down
8 changes: 0 additions & 8 deletions django/db/backends/sqlite3/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,6 @@ def adapt_datetimefield_value(self, value):
if value is None:
return None

# Expression values are adapted by the database.
if hasattr(value, "resolve_expression"):
return value

# SQLite doesn't support tz-aware datetimes
if timezone.is_aware(value):
if settings.USE_TZ:
Expand All @@ -283,10 +279,6 @@ def adapt_timefield_value(self, value):
if value is None:
return None

# Expression values are adapted by the database.
if hasattr(value, "resolve_expression"):
return value

# SQLite doesn't support tz-aware datetimes
if timezone.is_aware(value):
raise ValueError("SQLite backend does not support timezone-aware times.")
Expand Down
11 changes: 8 additions & 3 deletions django/db/models/lookups.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,16 @@ def get_db_prep_lookup(self, value, connection):
getattr(field, "get_db_prep_value", None)
or self.lhs.output_field.get_db_prep_value
)
if not self.get_db_prep_lookup_value_is_iterable:
value = [value]
return (
"%s",
[get_db_prep_value(v, connection, prepared=True) for v in value]
if self.get_db_prep_lookup_value_is_iterable
else [get_db_prep_value(value, connection, prepared=True)],
[
v
if hasattr(v, "as_sql")
else get_db_prep_value(v, connection, prepared=True)
for v in value
],
)


Expand Down
10 changes: 1 addition & 9 deletions tests/backends/base/test_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.core.management.color import no_style
from django.db import NotSupportedError, connection, transaction
from django.db.backends.base.operations import BaseDatabaseOperations
from django.db.models import DurationField, Value
from django.db.models import DurationField
from django.db.models.expressions import Col
from django.db.models.lookups import Exact
from django.test import (
Expand Down Expand Up @@ -89,17 +89,9 @@ def test_adapt_unknown_value_time(self):
def test_adapt_timefield_value_none(self):
self.assertIsNone(self.ops.adapt_timefield_value(None))

def test_adapt_timefield_value_expression(self):
value = Value(timezone.now().time())
self.assertEqual(self.ops.adapt_timefield_value(value), value)

def test_adapt_datetimefield_value_none(self):
self.assertIsNone(self.ops.adapt_datetimefield_value(None))

def test_adapt_datetimefield_value_expression(self):
value = Value(timezone.now())
self.assertEqual(self.ops.adapt_datetimefield_value(value), value)

def test_adapt_timefield_value(self):
msg = "Django does not support timezone-aware times."
with self.assertRaisesMessage(ValueError, msg):
Expand Down
18 changes: 14 additions & 4 deletions tests/expressions/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ def test_expressions_not_introduce_sql_injection_via_untrusted_string_inclusion(
queryset = Company.objects.filter(name__in=[F("num_chairs") + "1)) OR ((1==1"])
self.assertQuerySetEqual(queryset, [], ordered=False)

def test_range_lookup_allows_F_expressions_and_expressions_for_datetimes(self):
def test_range_lookup_allows_F_expressions_and_expressions_for_dates(self):
start = datetime.datetime(2016, 2, 3, 15, 0, 0)
end = datetime.datetime(2016, 2, 5, 15, 0, 0)
experiment_1 = Experiment.objects.create(
Expand Down Expand Up @@ -1256,9 +1256,19 @@ def test_range_lookup_allows_F_expressions_and_expressions_for_datetimes(self):
experiment=experiment_2,
result_time=datetime.datetime(2016, 1, 8, 5, 0, 0),
)
within_experiment_time = [F("experiment__start"), F("experiment__end")]
queryset = Result.objects.filter(result_time__range=within_experiment_time)
self.assertSequenceEqual(queryset, [r1])
tests = [
# Datetimes.
([F("experiment__start"), F("experiment__end")], "result_time__range"),
# Dates.
(
[F("experiment__start__date"), F("experiment__end__date")],
"result_time__date__range",
),
]
for within_experiment_time, lookup in tests:
with self.subTest(lookup=lookup):
queryset = Result.objects.filter(**{lookup: within_experiment_time})
self.assertSequenceEqual(queryset, [r1])


class FTests(SimpleTestCase):
Expand Down

0 comments on commit 0fcee16

Please sign in to comment.