Fixed #31620 -- Added support for %V format to WeekMixin/WeekArchiveView.

Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
This commit is contained in:
Hasan Ramezani 2020-06-25 23:00:51 +02:00 committed by Mariusz Felisiak
parent d2c135da4c
commit 8984cab8a8
6 changed files with 55 additions and 9 deletions

View File

@ -218,7 +218,7 @@ class WeekMixin:
The first day according to the week format is 0 and the last day is 6.
"""
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()
elif week_format == '%U': # week starts on Sunday
return (date.weekday() + 1) % 7
@ -485,7 +485,7 @@ class BaseWeekArchiveView(YearMixin, WeekMixin, BaseDateListView):
date_field = self.get_date_field()
week_format = self.get_week_format()
week_choices = {'%W': '1', '%U': '0'}
week_choices = {'%W': '1', '%U': '0', '%V': '1'}
try:
week_start = week_choices[week_format]
except KeyError:
@ -493,10 +493,15 @@ class BaseWeekArchiveView(YearMixin, WeekMixin, BaseDateListView):
week_format,
', '.join(sorted(week_choices)),
))
date = _date_from_string(year, self.get_year_format(),
week_start, '%w',
week, week_format)
year_format = self.get_year_format()
if week_format == '%V' and year_format != '%G':
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)
until = self._make_date_lookup_arg(self._get_next_week(date))
lookup_kwargs = {

View File

@ -342,6 +342,12 @@ views for displaying drilldown pages for date-based data.
* ``'%W'``: Similar to ``'%U'``, except it assumes that the week
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**::
from django.views.generic.dates import WeekArchiveView

View File

@ -180,7 +180,12 @@ Date-based mixins
The :func:`~time.strftime` format to use when parsing the week. By
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

View File

@ -166,7 +166,10 @@ Forms
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
~~~~~~~~~~~~~~~~~~~~

View File

@ -538,10 +538,29 @@ class WeekArchiveViewTests(TestDataMixin, TestCase):
self.assertEqual(res.status_code, 200)
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):
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/')
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):
BookSigning.objects.create(event_date=datetime.datetime(2008, 4, 2, 12, 0))
res = self.client.get('/dates/booksignings/2008/week/13/')

View File

@ -190,6 +190,14 @@ urlpatterns = [
'dates/books/<int:year>/week/<int:week>/unknown_week_format/',
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()),
# DayArchiveView