Code

Ticket #3585: gv_datebased_object_date.diff

File gv_datebased_object_date.diff, 8.8 KB (added by Per Jonsson <poj@…>, 7 years ago)
Line 
1Index: django/views/generic/date_based.py
2===================================================================
3--- django/views/generic/date_based.py  (revision 4608)
4+++ django/views/generic/date_based.py  (working copy)
5@@ -106,11 +106,15 @@
6         month:
7             (date) this month
8         next_month:
9-            (date) the first day of the next month, or None if the next month is in the future
10+            (date) the first day of the next month, or None if the next month is in the future and allow_future is False
11         previous_month:
12             (date) the first day of the previous month
13         object_list:
14             list of objects published in the given month
15+        next_object_date:
16+            (date) the date for the first object after the beginning of the next month, or None if there is no such object or if the date is in the future and allow_future is False
17+        previous_object_date:
18+            (date) the date for the last object before the beginning of the this month, or None if there is no such object
19     """
20     if extra_context is None: extra_context = {}
21     try:
22@@ -144,6 +148,25 @@
23     else:
24         next_month = None
25 
26+    # Get the closest past object's date, if it exists.
27+    lookup_kwargs = {'%s__lt' % date_field: first_day}
28+    previous_list = queryset.filter(**lookup_kwargs).order_by('-%s' % date_field)
29+    if previous_list:
30+        previous_object_date = getattr(previous_list[0], date_field).date()
31+    else:
32+        previous_object_date = None
33+
34+    # Get the closest future object's date, if it exists and is allowed
35+    if last_day >= now.date() and not allow_future:
36+        next_object_date = None
37+    else:
38+        lookup_kwargs = {'%s__gte' % date_field: last_day}
39+        next_list = queryset.filter(**lookup_kwargs).order_by(date_field)
40+        if next_list:
41+            next_object_date = getattr(next_list[0], date_field).date()
42+        else:
43+            next_object_date = None
44+
45     if not template_name:
46         template_name = "%s/%s_archive_month.html" % (model._meta.app_label, model._meta.object_name.lower())
47     t = template_loader.get_template(template_name)
48@@ -152,6 +175,8 @@
49         'month': date,
50         'next_month': next_month,
51         'previous_month': first_day - datetime.timedelta(days=1),
52+        'next_%s_date' % template_object_name: next_object_date,
53+        'previous_%s_date' % template_object_name: previous_object_date,
54     }, context_processors)
55     for key, value in extra_context.items():
56         if callable(value):
57@@ -225,7 +250,11 @@
58         previous_day
59             (datetime) the previous day
60         next_day
61-            (datetime) the next day, or None if the current day is today
62+            (datetime) the next day, or None if the current day is today and allow_future is False
63+        next_object_date:
64+            (date) the date for the first object after the beginning of the next month, or None if there is no such object or if the date is in the future and allow_future is False
65+        previous_object_date:
66+            (date) the date for the last object before the beginning of the this month, or None if there is no such object
67     """
68     if extra_context is None: extra_context = {}
69     try:
70@@ -256,6 +285,32 @@
71     else:
72         next_day = None
73 
74+    # Get the closest past object's date, if it exists.
75+    if isinstance(model._meta.get_field(date_field), DateTimeField):
76+        lookup_kwargs = {'%s__lt' % date_field: datetime.datetime.combine(date, datetime.time.min)}
77+    else:
78+        lookup_kwargs = {'%s__lt' % date_field: date}
79+    previous_list = queryset.filter(**lookup_kwargs).order_by('-%s' % date_field)
80+    if previous_list:
81+        previous_object_date = getattr(previous_list[0], date_field).date()
82+    else:
83+        previous_object_date = None
84+
85+    # Get the closest future object's date, if it exists and is allowed
86+    if date >= now.date() and not allow_future:
87+        next_object_date = None
88+    else:
89+        if isinstance(model._meta.get_field(date_field), DateTimeField):
90+            lookup_kwargs = {'%s__gt' % date_field: datetime.datetime.combine(date, datetime.time.min)}
91+        else:
92+            lookup_kwargs = {'%s__gt' % date_field: date}
93+        next_list = queryset.filter(**lookup_kwargs).order_by(date_field)
94+        if next_list:
95+            next_object_date = getattr(next_list[0], date_field).date()
96+        else:
97+            next_object_date = None
98+
99+
100     if not template_name:
101         template_name = "%s/%s_archive_day.html" % (model._meta.app_label, model._meta.object_name.lower())
102     t = template_loader.get_template(template_name)
103@@ -264,6 +319,8 @@
104         'day': date,
105         'previous_day': date - datetime.timedelta(days=1),
106         'next_day': next_day,
107+        'next_%s_date' % template_object_name: next_object_date,
108+        'previous_%s_date' % template_object_name: previous_object_date,
109     }, context_processors)
110     for key, value in extra_context.items():
111         if callable(value):
112Index: docs/generic_views.txt
113===================================================================
114--- docs/generic_views.txt      (revision 4608)
115+++ docs/generic_views.txt      (working copy)
116@@ -384,18 +384,36 @@
117     * ``month``: A ``datetime.date`` object representing the given month.
118 
119     * ``next_month``: A ``datetime.date`` object representing the first day of
120-      the next month. If the next month is in the future, this will be
121-      ``None``.
122+      the next month. If the next month is in the future and ``allow_future`` is
123+      ``False``, this will be ``None``.
124 
125     * ``previous_month``: A ``datetime.date`` object representing the first day
126       of the previous month. Unlike ``next_month``, this will never be
127       ``None``.
128 
129+    * ``previous_month``: A ``datetime.date`` object representing the day of the
130+      last post of the previous month. If there is no such post this will be
131+      ``None``.
132+
133     * ``object_list``: A list of objects available for the given month. This
134       variable's name depends on the ``template_object_name`` parameter, which
135       is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
136       this variable's name will be ``foo_list``.
137 
138+    * ``next_object_date``: A ``datetime.date`` object representing the date of the
139+      first object dated after the start of next month. If there is no such object
140+      or if the date is in the future and ``allow_future`` is ``False``, this will
141+      be ``None``. This variable's name depends on the ``template_object_name``
142+      parameter, which is ``'object'`` by default. If ``template_object_name`` is
143+      ``'foo'``, this variable's name will be ``next_foo_date``.
144+
145+    * ``previous_object_date``: A ``datetime.date`` object representing the date of
146+      the last object dated before the start of the given month. If there is no such
147+      object, this will be ``None``. This variable's name depends on the
148+      ``template_object_name`` parameter, which is ``'object'`` by default.
149+      If ``template_object_name`` is ``'foo'``, this variable's name will be
150+      ``previous_foo_date``.
151+
152 .. _strftime docs: http://www.python.org/doc/current/lib/module-time.html#l2h-1941
153 
154 ``django.views.generic.date_based.archive_week``
155@@ -550,7 +568,8 @@
156     * ``day``: A ``datetime.date`` object representing the given day.
157 
158     * ``next_day``: A ``datetime.date`` object representing the next day. If
159-      the next day is in the future, this will be ``None``.
160+      the next day is in the future, and ``allow_future`` is ``False``, this
161+      will be ``None``.
162 
163     * ``previous_day``: A ``datetime.date`` object representing the given day.
164       Unlike ``next_day``, this will never be ``None``.
165@@ -560,6 +579,20 @@
166       is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
167       this variable's name will be ``foo_list``.
168 
169+    * ``next_object_date``: A ``datetime.date`` object representing the date of the
170+      first object dated after the given day. If there is no such object or if the
171+      date is in the future and ``allow_future`` is ``False``, this will be ``None``.
172+      This variable's name depends on the ``template_object_name`` parameter, which
173+      is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
174+      this variable's name will be ``next_foo_date``.
175+
176+    * ``previous_object_date``: A ``datetime.date`` object representing the date of
177+      the last object dated before the given day. If there is no such object, this
178+      will be ``None``. This variable's name depends on the ``template_object_name``
179+      parameter, which is ``'object'`` by default. If ``template_object_name`` is
180+      ``'foo'``, this variable's name will be ``previous_foo_date``.
181+
182+
183 ``django.views.generic.date_based.archive_today``
184 -------------------------------------------------
185