Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
a455e732
Kaydet (Commit)
a455e732
authored
Eyl 28, 2017
tarafından
Sigurd Ljødal
Kaydeden (comit)
Tim Graham
Ock 27, 2018
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #28650 -- Added TruncWeek database function.
üst
f229049d
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
116 additions
and
16 deletions
+116
-16
operations.py
django/db/backends/mysql/operations.py
+10
-0
operations.py
django/db/backends/oracle/operations.py
+4
-0
base.py
django/db/backends/sqlite3/base.py
+6
-0
__init__.py
django/db/models/functions/__init__.py
+2
-2
datetime.py
django/db/models/functions/datetime.py
+7
-1
query.py
django/db/models/query.py
+4
-4
database-functions.txt
docs/ref/models/database-functions.txt
+10
-0
querysets.txt
docs/ref/models/querysets.txt
+18
-6
2.1.txt
docs/releases/2.1.txt
+4
-0
tests.py
tests/dates/tests.py
+8
-1
tests.py
tests/datetimes/tests.py
+9
-0
test_datetime.py
tests/db_functions/test_datetime.py
+34
-2
No files found.
django/db/backends/mysql/operations.py
Dosyayı görüntüle @
a455e732
...
...
@@ -53,6 +53,10 @@ class DatabaseOperations(BaseDatabaseOperations):
return
"MAKEDATE(YEAR(
%
s), 1) + INTERVAL QUARTER(
%
s) QUARTER - INTERVAL 1 QUARTER"
%
(
field_name
,
field_name
)
elif
lookup_type
==
'week'
:
return
"DATE_SUB(
%
s, INTERVAL WEEKDAY(
%
s) DAY)"
%
(
field_name
,
field_name
)
else
:
return
"DATE(
%
s)"
%
(
field_name
)
...
...
@@ -84,6 +88,12 @@ class DatabaseOperations(BaseDatabaseOperations):
"INTERVAL QUARTER({field_name}) QUARTER - "
+
"INTERVAL 1 QUARTER, '
%%
Y-
%%
m-01 00:00:00') AS DATETIME)"
)
.
format
(
field_name
=
field_name
)
if
lookup_type
==
'week'
:
return
(
"CAST(DATE_FORMAT(DATE_SUB({field_name}, "
"INTERVAL WEEKDAY({field_name}) DAY), "
"'
%%
Y-
%%
m-
%%
d 00:00:00') AS DATETIME)"
)
.
format
(
field_name
=
field_name
)
try
:
i
=
fields
.
index
(
lookup_type
)
+
1
except
ValueError
:
...
...
django/db/backends/oracle/operations.py
Dosyayı görüntüle @
a455e732
...
...
@@ -78,6 +78,8 @@ END;
return
"TRUNC(
%
s, '
%
s')"
%
(
field_name
,
lookup_type
.
upper
())
elif
lookup_type
==
'quarter'
:
return
"TRUNC(
%
s, 'Q')"
%
field_name
elif
lookup_type
==
'week'
:
return
"TRUNC(
%
s, 'IW')"
%
field_name
else
:
return
"TRUNC(
%
s)"
%
field_name
...
...
@@ -116,6 +118,8 @@ END;
sql
=
"TRUNC(
%
s, '
%
s')"
%
(
field_name
,
lookup_type
.
upper
())
elif
lookup_type
==
'quarter'
:
sql
=
"TRUNC(
%
s, 'Q')"
%
field_name
elif
lookup_type
==
'week'
:
sql
=
"TRUNC(
%
s, 'IW')"
%
field_name
elif
lookup_type
==
'day'
:
sql
=
"TRUNC(
%
s)"
%
field_name
elif
lookup_type
==
'hour'
:
...
...
django/db/backends/sqlite3/base.py
Dosyayı görüntüle @
a455e732
...
...
@@ -335,6 +335,9 @@ def _sqlite_date_trunc(lookup_type, dt):
return
'
%
i-
%02
i-01'
%
(
dt
.
year
,
month_in_quarter
)
elif
lookup_type
==
'month'
:
return
"
%
i-
%02
i-01"
%
(
dt
.
year
,
dt
.
month
)
elif
lookup_type
==
'week'
:
dt
=
dt
-
datetime
.
timedelta
(
days
=
dt
.
weekday
())
return
"
%
i-
%02
i-
%02
i"
%
(
dt
.
year
,
dt
.
month
,
dt
.
day
)
elif
lookup_type
==
'day'
:
return
"
%
i-
%02
i-
%02
i"
%
(
dt
.
year
,
dt
.
month
,
dt
.
day
)
...
...
@@ -403,6 +406,9 @@ def _sqlite_datetime_trunc(lookup_type, dt, tzname):
return
'
%
i-
%02
i-01 00:00:00'
%
(
dt
.
year
,
month_in_quarter
)
elif
lookup_type
==
'month'
:
return
"
%
i-
%02
i-01 00:00:00"
%
(
dt
.
year
,
dt
.
month
)
elif
lookup_type
==
'week'
:
dt
=
dt
-
datetime
.
timedelta
(
days
=
dt
.
weekday
())
return
"
%
i-
%02
i-
%02
i 00:00:00"
%
(
dt
.
year
,
dt
.
month
,
dt
.
day
)
elif
lookup_type
==
'day'
:
return
"
%
i-
%02
i-
%02
i 00:00:00"
%
(
dt
.
year
,
dt
.
month
,
dt
.
day
)
elif
lookup_type
==
'hour'
:
...
...
django/db/models/functions/__init__.py
Dosyayı görüntüle @
a455e732
...
...
@@ -3,7 +3,7 @@ from .datetime import (
Extract
,
ExtractDay
,
ExtractHour
,
ExtractMinute
,
ExtractMonth
,
ExtractQuarter
,
ExtractSecond
,
ExtractWeek
,
ExtractWeekDay
,
ExtractYear
,
Now
,
Trunc
,
TruncDate
,
TruncDay
,
TruncHour
,
TruncMinute
,
TruncMonth
,
TruncQuarter
,
TruncSecond
,
TruncTime
,
TruncYear
,
TruncQuarter
,
TruncSecond
,
TruncTime
,
Trunc
Week
,
Trunc
Year
,
)
from
.text
import
(
Concat
,
ConcatPair
,
Length
,
Lower
,
Replace
,
StrIndex
,
Substr
,
Upper
,
...
...
@@ -21,7 +21,7 @@ __all__ = [
'ExtractQuarter'
,
'ExtractSecond'
,
'ExtractWeek'
,
'ExtractWeekDay'
,
'ExtractYear'
,
'Now'
,
'Trunc'
,
'TruncDate'
,
'TruncDay'
,
'TruncHour'
,
'TruncMinute'
,
'TruncMonth'
,
'TruncQuarter'
,
'TruncSecond'
,
'TruncTime'
,
'TruncYear'
,
'Trunc
Week'
,
'Trunc
Year'
,
# text
'Concat'
,
'ConcatPair'
,
'Length'
,
'Lower'
,
'Replace'
,
'StrIndex'
,
'Substr'
,
'Upper'
,
...
...
django/db/models/functions/datetime.py
Dosyayı görüntüle @
a455e732
...
...
@@ -199,7 +199,8 @@ class TruncBase(TimezoneMixin, Transform):
field
.
name
,
output_field
.
__class__
.
__name__
if
has_explicit_output_field
else
'DateTimeField'
))
elif
isinstance
(
field
,
TimeField
)
and
(
isinstance
(
output_field
,
DateTimeField
)
or
copy
.
kind
in
(
'year'
,
'quarter'
,
'month'
,
'day'
,
'date'
)):
isinstance
(
output_field
,
DateTimeField
)
or
copy
.
kind
in
(
'year'
,
'quarter'
,
'month'
,
'week'
,
'day'
,
'date'
)):
raise
ValueError
(
"Cannot truncate TimeField '
%
s' to
%
s. "
%
(
field
.
name
,
output_field
.
__class__
.
__name__
if
has_explicit_output_field
else
'DateTimeField'
))
...
...
@@ -242,6 +243,11 @@ class TruncMonth(TruncBase):
kind
=
'month'
class
TruncWeek
(
TruncBase
):
"""Truncate to midnight on the Monday of the week."""
kind
=
'week'
class
TruncDay
(
TruncBase
):
kind
=
'day'
...
...
django/db/models/query.py
Dosyayı görüntüle @
a455e732
...
...
@@ -777,8 +777,8 @@ class QuerySet:
Return a list of date objects representing all available dates for
the given field_name, scoped to 'kind'.
"""
assert
kind
in
(
"year"
,
"month"
,
"day"
),
\
"'kind' must be one of 'year', 'month' or 'day'."
assert
kind
in
(
'year'
,
'month'
,
'week'
,
'day'
),
\
"'kind' must be one of 'year', 'month'
, 'week',
or 'day'."
assert
order
in
(
'ASC'
,
'DESC'
),
\
"'order' must be either 'ASC' or 'DESC'."
return
self
.
annotate
(
...
...
@@ -793,8 +793,8 @@ class QuerySet:
Return a list of datetime objects representing all available
datetimes for the given field_name, scoped to 'kind'.
"""
assert
kind
in
(
"year"
,
"month"
,
"day"
,
"hour"
,
"minute"
,
"second"
),
\
"'kind' must be one of 'year', 'month', '
day', 'hour', 'minute'
or 'second'."
assert
kind
in
(
'year'
,
'month'
,
'week'
,
'day'
,
'hour'
,
'minute'
,
'second'
),
\
"'kind' must be one of 'year', 'month', '
week', 'day', 'hour', 'minute',
or 'second'."
assert
order
in
(
'ASC'
,
'DESC'
),
\
"'order' must be either 'ASC' or 'DESC'."
if
settings
.
USE_TZ
:
...
...
docs/ref/models/database-functions.txt
Dosyayı görüntüle @
a455e732
...
...
@@ -439,6 +439,7 @@ return:
* "year": 2015-01-01 00:00:00+00:00
* "quarter": 2015-04-01 00:00:00+00:00
* "month": 2015-06-01 00:00:00+00:00
* "week": 2015-06-15 00:00:00+00:00
* "day": 2015-06-15 00:00:00+00:00
* "hour": 2015-06-15 14:00:00+00:00
* "minute": 2015-06-15 14:30:00+00:00
...
...
@@ -452,6 +453,7 @@ values returned when this timezone is active will be:
* "year": 2015-01-01 00:00:00+11:00
* "quarter": 2015-04-01 00:00:00+10:00
* "month": 2015-06-01 00:00:00+10:00
* "week": 2015-06-16 00:00:00+10:00
* "day": 2015-06-16 00:00:00+10:00
* "hour": 2015-06-16 00:00:00+10:00
* "minute": 2015-06-16 00:30:00+10:00
...
...
@@ -504,6 +506,14 @@ Usage example::
.. attribute:: kind = 'month'
.. class:: TruncWeek(expression, output_field=None, tzinfo=None, **extra)
.. versionadded:: 2.1
Truncates to midnight on the Monday of the week.
.. attribute:: kind = 'week'
.. class:: TruncQuarter(expression, output_field=None, tzinfo=None, **extra)
.. versionadded:: 2.0
...
...
docs/ref/models/querysets.txt
Dosyayı görüntüle @
a455e732
...
...
@@ -694,13 +694,15 @@ objects representing all available dates of a particular kind within the
contents of the ``QuerySet``.
``field`` should be the name of a ``DateField`` of your model.
``kind`` should be either ``"year"``, ``"month"``
or ``"day"``. Each
``datetime.date`` object in the result list is "truncated" to the given
``type``.
``kind`` should be either ``"year"``, ``"month"``
, ``"week"``, or ``"day"``.
Each :class:`datetime.date` object in the result list is "truncated" to the
given
``type``.
* ``"year"`` returns a list of all distinct year values for the field.
* ``"month"`` returns a list of all distinct year/month values for the
field.
* ``"week"`` returns a list of all distinct year/week values for the field. All
dates will be a Monday.
* ``"day"`` returns a list of all distinct year/month/day values for the
field.
...
...
@@ -713,6 +715,8 @@ Examples::
[datetime.date(2005, 1, 1)]
>>> Entry.objects.dates('pub_date', 'month')
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]
>>> Entry.objects.dates('pub_date', 'week')
[datetime.date(2005, 2, 14), datetime.date(2005, 3, 14)]
>>> Entry.objects.dates('pub_date', 'day')
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
...
...
@@ -720,6 +724,10 @@ Examples::
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.date(2005, 3, 20)]
.. versionchanged:: 2.1
"week" support was added.
``datetimes()``
~~~~~~~~~~~~~~~
...
...
@@ -731,9 +739,9 @@ contents of the ``QuerySet``.
``field_name`` should be the name of a ``DateTimeField`` of your model.
``kind`` should be either ``"year"``, ``"month"``, ``"
day"``, ``"hour
"``,
``"
minute"`` or ``"second"``. Each ``datetime.datetime`` object in the result
list is "truncated" to the given ``type``.
``kind`` should be either ``"year"``, ``"month"``, ``"
week"``, ``"day
"``,
``"
hour"``, ``"minute"``, or ``"second"``. Each :class:`datetime.datetime`
object in the result
list is "truncated" to the given ``type``.
``order``, which defaults to ``'ASC'``, should be either ``'ASC'`` or
``'DESC'``. This specifies how to order the results.
...
...
@@ -745,6 +753,10 @@ object. If it's ``None``, Django uses the :ref:`current time zone
<default-current-time-zone>`. It has no effect when :setting:`USE_TZ` is
``False``.
.. versionchanged:: 2.1
"week" support was added.
.. _database-time-zone-definitions:
.. note::
...
...
docs/releases/2.1.txt
Dosyayı görüntüle @
a455e732
...
...
@@ -173,6 +173,10 @@ Models
* The new :class:`~django.db.models.functions.Replace` database function
replaces strings in an expression.
* The new :class:`~django.db.models.functions.TruncWeek` function truncates
:class:`~django.db.models.DateField` and
:class:`~django.db.models.DateTimeField` to the Monday of a week.
Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~
...
...
tests/dates/tests.py
Dosyayı görüntüle @
a455e732
...
...
@@ -55,6 +55,12 @@ class DatesTests(TestCase):
datetime
.
date
(
2010
,
7
,
1
),
],
)
self
.
assertSequenceEqual
(
Comment
.
objects
.
dates
(
"article__pub_date"
,
"week"
),
[
datetime
.
date
(
2005
,
7
,
25
),
datetime
.
date
(
2010
,
7
,
26
),
],
)
self
.
assertSequenceEqual
(
Comment
.
objects
.
dates
(
"article__pub_date"
,
"day"
),
[
datetime
.
date
(
2005
,
7
,
28
),
...
...
@@ -93,7 +99,8 @@ class DatesTests(TestCase):
)
def
test_dates_fails_when_given_invalid_kind_argument
(
self
):
with
self
.
assertRaisesMessage
(
AssertionError
,
"'kind' must be one of 'year', 'month' or 'day'."
):
msg
=
"'kind' must be one of 'year', 'month', 'week', or 'day'."
with
self
.
assertRaisesMessage
(
AssertionError
,
msg
):
Article
.
objects
.
dates
(
"pub_date"
,
"bad_kind"
)
def
test_dates_fails_when_given_invalid_order_argument
(
self
):
...
...
tests/datetimes/tests.py
Dosyayı görüntüle @
a455e732
...
...
@@ -53,6 +53,12 @@ class DateTimesTests(TestCase):
datetime
.
datetime
(
2010
,
7
,
1
),
],
)
self
.
assertSequenceEqual
(
Comment
.
objects
.
datetimes
(
"article__pub_date"
,
"week"
),
[
datetime
.
datetime
(
2005
,
7
,
25
),
datetime
.
datetime
(
2010
,
7
,
26
),
],
)
self
.
assertSequenceEqual
(
Comment
.
objects
.
datetimes
(
"article__pub_date"
,
"day"
),
[
datetime
.
datetime
(
2005
,
7
,
28
),
...
...
@@ -98,6 +104,9 @@ class DateTimesTests(TestCase):
self
.
assertQuerysetEqual
(
Article
.
objects
.
datetimes
(
'pub_date'
,
'month'
),
[
"datetime.datetime(2005, 7, 1, 0, 0)"
])
self
.
assertQuerysetEqual
(
Article
.
objects
.
datetimes
(
'pub_date'
,
'week'
),
[
"datetime.datetime(2005, 7, 25, 0, 0)"
])
self
.
assertQuerysetEqual
(
Article
.
objects
.
datetimes
(
'pub_date'
,
'day'
),
[
"datetime.datetime(2005, 7, 28, 0, 0)"
,
...
...
tests/db_functions/test_datetime.py
Dosyayı görüntüle @
a455e732
from
datetime
import
datetime
from
datetime
import
datetime
,
timedelta
import
pytz
...
...
@@ -8,7 +8,7 @@ from django.db.models.functions import (
Extract
,
ExtractDay
,
ExtractHour
,
ExtractMinute
,
ExtractMonth
,
ExtractQuarter
,
ExtractSecond
,
ExtractWeek
,
ExtractWeekDay
,
ExtractYear
,
Trunc
,
TruncDate
,
TruncDay
,
TruncHour
,
TruncMinute
,
TruncMonth
,
TruncQuarter
,
TruncSecond
,
TruncTime
,
TruncYear
,
TruncQuarter
,
TruncSecond
,
TruncTime
,
Trunc
Week
,
Trunc
Year
,
)
from
django.test
import
(
TestCase
,
override_settings
,
skipIfDBFeature
,
skipUnlessDBFeature
,
...
...
@@ -34,6 +34,10 @@ def truncate_to(value, kind, tzinfo=None):
if
isinstance
(
value
,
datetime
):
return
value
.
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
,
microsecond
=
0
)
return
value
if
kind
==
'week'
:
if
isinstance
(
value
,
datetime
):
return
(
value
-
timedelta
(
days
=
value
.
weekday
()))
.
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
,
microsecond
=
0
)
return
value
-
timedelta
(
days
=
value
.
weekday
())
if
kind
==
'month'
:
if
isinstance
(
value
,
datetime
):
return
value
.
replace
(
day
=
1
,
hour
=
0
,
minute
=
0
,
second
=
0
,
microsecond
=
0
)
...
...
@@ -536,6 +540,7 @@ class DateFunctionTests(TestCase):
test_date_kind
(
'year'
)
test_date_kind
(
'quarter'
)
test_date_kind
(
'month'
)
test_date_kind
(
'week'
)
test_date_kind
(
'day'
)
test_time_kind
(
'hour'
)
test_time_kind
(
'minute'
)
...
...
@@ -543,6 +548,7 @@ class DateFunctionTests(TestCase):
test_datetime_kind
(
'year'
)
test_datetime_kind
(
'quarter'
)
test_datetime_kind
(
'month'
)
test_datetime_kind
(
'week'
)
test_datetime_kind
(
'day'
)
test_datetime_kind
(
'hour'
)
test_datetime_kind
(
'minute'
)
...
...
@@ -656,6 +662,30 @@ class DateFunctionTests(TestCase):
with
self
.
assertRaisesMessage
(
ValueError
,
"Cannot truncate TimeField 'start_time' to DateTimeField"
):
list
(
DTModel
.
objects
.
annotate
(
truncated
=
TruncMonth
(
'start_time'
,
output_field
=
TimeField
())))
def
test_trunc_week_func
(
self
):
start_datetime
=
datetime
(
2015
,
6
,
15
,
14
,
30
,
50
,
321
)
end_datetime
=
truncate_to
(
datetime
(
2016
,
6
,
15
,
14
,
10
,
50
,
123
),
'week'
)
if
settings
.
USE_TZ
:
start_datetime
=
timezone
.
make_aware
(
start_datetime
,
is_dst
=
False
)
end_datetime
=
timezone
.
make_aware
(
end_datetime
,
is_dst
=
False
)
self
.
create_model
(
start_datetime
,
end_datetime
)
self
.
create_model
(
end_datetime
,
start_datetime
)
self
.
assertQuerysetEqual
(
DTModel
.
objects
.
annotate
(
extracted
=
TruncWeek
(
'start_datetime'
))
.
order_by
(
'start_datetime'
),
[
(
start_datetime
,
truncate_to
(
start_datetime
,
'week'
)),
(
end_datetime
,
truncate_to
(
end_datetime
,
'week'
)),
],
lambda
m
:
(
m
.
start_datetime
,
m
.
extracted
)
)
self
.
assertEqual
(
DTModel
.
objects
.
filter
(
start_datetime
=
TruncWeek
(
'start_datetime'
))
.
count
(),
1
)
with
self
.
assertRaisesMessage
(
ValueError
,
"Cannot truncate TimeField 'start_time' to DateTimeField"
):
list
(
DTModel
.
objects
.
annotate
(
truncated
=
TruncWeek
(
'start_time'
)))
with
self
.
assertRaisesMessage
(
ValueError
,
"Cannot truncate TimeField 'start_time' to DateTimeField"
):
list
(
DTModel
.
objects
.
annotate
(
truncated
=
TruncWeek
(
'start_time'
,
output_field
=
TimeField
())))
def
test_trunc_date_func
(
self
):
start_datetime
=
datetime
(
2015
,
6
,
15
,
14
,
30
,
50
,
321
)
end_datetime
=
datetime
(
2016
,
6
,
15
,
14
,
10
,
50
,
123
)
...
...
@@ -960,6 +990,7 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests):
test_date_kind
(
'year'
)
test_date_kind
(
'quarter'
)
test_date_kind
(
'month'
)
test_date_kind
(
'week'
)
test_date_kind
(
'day'
)
test_time_kind
(
'hour'
)
test_time_kind
(
'minute'
)
...
...
@@ -967,6 +998,7 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests):
test_datetime_kind
(
'year'
)
test_datetime_kind
(
'quarter'
)
test_datetime_kind
(
'month'
)
test_datetime_kind
(
'week'
)
test_datetime_kind
(
'day'
)
test_datetime_kind
(
'hour'
)
test_datetime_kind
(
'minute'
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment