Fixed #31620 -- Added support for %V format to WeekMixin/WeekArchiveView.
Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
This commit is contained in:
parent
d2c135da4c
commit
8984cab8a8
|
@ -218,7 +218,7 @@ class WeekMixin:
|
||||||
The first day according to the week format is 0 and the last day is 6.
|
The first day according to the week format is 0 and the last day is 6.
|
||||||
"""
|
"""
|
||||||
week_format = self.get_week_format()
|
week_format = self.get_week_format()
|
||||||
if week_format == '%W': # week starts on Monday
|
if week_format in {'%W', '%V'}: # week starts on Monday
|
||||||
return date.weekday()
|
return date.weekday()
|
||||||
elif week_format == '%U': # week starts on Sunday
|
elif week_format == '%U': # week starts on Sunday
|
||||||
return (date.weekday() + 1) % 7
|
return (date.weekday() + 1) % 7
|
||||||
|
@ -485,7 +485,7 @@ class BaseWeekArchiveView(YearMixin, WeekMixin, BaseDateListView):
|
||||||
|
|
||||||
date_field = self.get_date_field()
|
date_field = self.get_date_field()
|
||||||
week_format = self.get_week_format()
|
week_format = self.get_week_format()
|
||||||
week_choices = {'%W': '1', '%U': '0'}
|
week_choices = {'%W': '1', '%U': '0', '%V': '1'}
|
||||||
try:
|
try:
|
||||||
week_start = week_choices[week_format]
|
week_start = week_choices[week_format]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -493,10 +493,15 @@ class BaseWeekArchiveView(YearMixin, WeekMixin, BaseDateListView):
|
||||||
week_format,
|
week_format,
|
||||||
', '.join(sorted(week_choices)),
|
', '.join(sorted(week_choices)),
|
||||||
))
|
))
|
||||||
date = _date_from_string(year, self.get_year_format(),
|
year_format = self.get_year_format()
|
||||||
week_start, '%w',
|
if week_format == '%V' and year_format != '%G':
|
||||||
week, week_format)
|
raise ValueError(
|
||||||
|
"ISO week directive '%s' is incompatible with the year "
|
||||||
|
"directive '%s'. Use the ISO year '%%G' instead." % (
|
||||||
|
week_format, year_format,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
date = _date_from_string(year, year_format, week_start, '%w', week, week_format)
|
||||||
since = self._make_date_lookup_arg(date)
|
since = self._make_date_lookup_arg(date)
|
||||||
until = self._make_date_lookup_arg(self._get_next_week(date))
|
until = self._make_date_lookup_arg(self._get_next_week(date))
|
||||||
lookup_kwargs = {
|
lookup_kwargs = {
|
||||||
|
|
|
@ -342,6 +342,12 @@ views for displaying drilldown pages for date-based data.
|
||||||
* ``'%W'``: Similar to ``'%U'``, except it assumes that the week
|
* ``'%W'``: Similar to ``'%U'``, except it assumes that the week
|
||||||
begins on Monday. This is not the same as the ISO 8601 week number.
|
begins on Monday. This is not the same as the ISO 8601 week number.
|
||||||
|
|
||||||
|
* ``'%V'``: ISO 8601 week number where the week begins on Monday.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
Support for the ``'%V'`` week format was added.
|
||||||
|
|
||||||
**Example myapp/views.py**::
|
**Example myapp/views.py**::
|
||||||
|
|
||||||
from django.views.generic.dates import WeekArchiveView
|
from django.views.generic.dates import WeekArchiveView
|
||||||
|
|
|
@ -180,7 +180,12 @@ Date-based mixins
|
||||||
|
|
||||||
The :func:`~time.strftime` format to use when parsing the week. By
|
The :func:`~time.strftime` format to use when parsing the week. By
|
||||||
default, this is ``'%U'``, which means the week starts on Sunday. Set
|
default, this is ``'%U'``, which means the week starts on Sunday. Set
|
||||||
it to ``'%W'`` if your week starts on Monday.
|
it to ``'%W'`` or ``'%V'`` (ISO 8601 week) if your week starts on
|
||||||
|
Monday.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
Support for the ``'%V'`` week format was added.
|
||||||
|
|
||||||
.. attribute:: week
|
.. attribute:: week
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,10 @@ Forms
|
||||||
Generic Views
|
Generic Views
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* The ``week_format`` attributes of
|
||||||
|
:class:`~django.views.generic.dates.WeekMixin` and
|
||||||
|
:class:`~django.views.generic.dates.WeekArchiveView` now support the
|
||||||
|
``'%V'`` ISO 8601 week format.
|
||||||
|
|
||||||
Internationalization
|
Internationalization
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -538,10 +538,29 @@ class WeekArchiveViewTests(TestDataMixin, TestCase):
|
||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
self.assertEqual(res.context['week'], datetime.date(2008, 9, 29))
|
self.assertEqual(res.context['week'], datetime.date(2008, 9, 29))
|
||||||
|
|
||||||
|
def test_week_iso_format(self):
|
||||||
|
res = self.client.get('/dates/books/2008/week/40/iso_format/')
|
||||||
|
self.assertEqual(res.status_code, 200)
|
||||||
|
self.assertTemplateUsed(res, 'generic_views/book_archive_week.html')
|
||||||
|
self.assertEqual(
|
||||||
|
list(res.context['book_list']),
|
||||||
|
[Book.objects.get(pubdate=datetime.date(2008, 10, 1))],
|
||||||
|
)
|
||||||
|
self.assertEqual(res.context['week'], datetime.date(2008, 9, 29))
|
||||||
|
|
||||||
def test_unknown_week_format(self):
|
def test_unknown_week_format(self):
|
||||||
with self.assertRaisesMessage(ValueError, "Unknown week format '%T'. Choices are: %U, %W"):
|
msg = "Unknown week format '%T'. Choices are: %U, %V, %W"
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
self.client.get('/dates/books/2008/week/39/unknown_week_format/')
|
self.client.get('/dates/books/2008/week/39/unknown_week_format/')
|
||||||
|
|
||||||
|
def test_incompatible_iso_week_format_view(self):
|
||||||
|
msg = (
|
||||||
|
"ISO week directive '%V' is incompatible with the year directive "
|
||||||
|
"'%Y'. Use the ISO year '%G' instead."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
|
self.client.get('/dates/books/2008/week/40/invalid_iso_week_year_format/')
|
||||||
|
|
||||||
def test_datetime_week_view(self):
|
def test_datetime_week_view(self):
|
||||||
BookSigning.objects.create(event_date=datetime.datetime(2008, 4, 2, 12, 0))
|
BookSigning.objects.create(event_date=datetime.datetime(2008, 4, 2, 12, 0))
|
||||||
res = self.client.get('/dates/booksignings/2008/week/13/')
|
res = self.client.get('/dates/booksignings/2008/week/13/')
|
||||||
|
|
|
@ -190,6 +190,14 @@ urlpatterns = [
|
||||||
'dates/books/<int:year>/week/<int:week>/unknown_week_format/',
|
'dates/books/<int:year>/week/<int:week>/unknown_week_format/',
|
||||||
views.BookWeekArchive.as_view(week_format='%T'),
|
views.BookWeekArchive.as_view(week_format='%T'),
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
'dates/books/<int:year>/week/<int:week>/iso_format/',
|
||||||
|
views.BookWeekArchive.as_view(year_format='%G', week_format='%V'),
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'dates/books/<int:year>/week/<int:week>/invalid_iso_week_year_format/',
|
||||||
|
views.BookWeekArchive.as_view(week_format='%V'),
|
||||||
|
),
|
||||||
path('dates/booksignings/<int:year>/week/<int:week>/', views.BookSigningWeekArchive.as_view()),
|
path('dates/booksignings/<int:year>/week/<int:week>/', views.BookSigningWeekArchive.as_view()),
|
||||||
|
|
||||||
# DayArchiveView
|
# DayArchiveView
|
||||||
|
|
Loading…
Reference in New Issue