如何在 Django 中组合查询集来显示日历事件?
How to combine querysets in Django to show calendar events?
我正在尝试创建一个日历,如果在 Event
模型中创建了事件以及 DateTimeField
。
,则在日期下方显示事件
这是我的代码:
views.py
from django.shortcuts import render
import calendar
from .models import Event
def Cal(request, year, month):
calendar.setfirstweekday(calendar.SUNDAY)
prev_year = int(year)
next_year = int(year)
prev_month = int(month) - 1
next_month = int(month) + 1
if prev_month == 0:
prev_year -= 1
prev_month = 12
if next_month == 13:
next_year += 1
next_month = 1
month_cal = calendar.monthcalendar(int(year), int(month))
events = Event.objects.filter(when__year=year, when__month=month)
return render(request, "cal/calendar.html", {
"month_cal": month_cal,
"prev_month": prev_month,
"next_month": next_month,
"prev_year": prev_year,
"next_year": next_year,
"events": events,
})
calendar.html
{% extends "base.html" %}
{% block body %}
<table border="1" cellspacing="0" cellpadding="10" width="40%" height="80%">
<tr>
<td>Sun</td>
<td>Mon</td>
<td>Tue</td>
<td>Wed</td>
<td>Thu</td>
<td>Fri</td>
<td>Sat</td>
</tr>
{% for week in month_cal %}
<tr>
{% for day in week %}
<td>
{% if day == 0 %}
-
{% else %}
{{ day }}
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<a href="{% url 'calendar:calendar' prev_year prev_month %}">previous</a>
<a href="{% url 'calendar:calendar' next_year next_month %}">next</a>
{% endblock %}
我能够成功地遍历所有事件并遍历日历中的所有日期。但是,我希望事件在适当的日期显示在日历中。
我建议在您的上下文中添加 {day_of_month: events}
的映射,而不是整个月所有事件的列表。这样,在构建模板时,您无需遍历每个月的每一天的所有事件。
这是一个示例实现:
views.py
from collections import defaultdict
...
def Cal(request, year, month):
...
events = Event.objects.filter(when__year=year, when__month=month)
event_days = defaultdict(list)
for event in events:
event_days[event.when.day].append(event)
return render(request, "cal/calendar.html", {
"month_cal": month_cal,
"prev_month": prev_month,
"next_month": next_month,
"prev_year": prev_year,
"next_year": next_year,
"event_days": event_days,
})
接下来,您需要 include a dict lookup template filter 在您的项目中。 (有关实施,请参阅相关问题。)
现在,当您循环浏览日历时,您可以轻松地按天访问事件:
calendar.html
...
{% for week in month_cal %}
<tr>
{% for day in week %}
<td>
{% if day == 0 %}
-
{% else %}
{{ day }}
{% for event in event_days|get_item:day %}
{# format the event here #}
{{ event.description }}
{% endfor %}
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
...
我正在尝试创建一个日历,如果在 Event
模型中创建了事件以及 DateTimeField
。
这是我的代码: views.py
from django.shortcuts import render
import calendar
from .models import Event
def Cal(request, year, month):
calendar.setfirstweekday(calendar.SUNDAY)
prev_year = int(year)
next_year = int(year)
prev_month = int(month) - 1
next_month = int(month) + 1
if prev_month == 0:
prev_year -= 1
prev_month = 12
if next_month == 13:
next_year += 1
next_month = 1
month_cal = calendar.monthcalendar(int(year), int(month))
events = Event.objects.filter(when__year=year, when__month=month)
return render(request, "cal/calendar.html", {
"month_cal": month_cal,
"prev_month": prev_month,
"next_month": next_month,
"prev_year": prev_year,
"next_year": next_year,
"events": events,
})
calendar.html
{% extends "base.html" %}
{% block body %}
<table border="1" cellspacing="0" cellpadding="10" width="40%" height="80%">
<tr>
<td>Sun</td>
<td>Mon</td>
<td>Tue</td>
<td>Wed</td>
<td>Thu</td>
<td>Fri</td>
<td>Sat</td>
</tr>
{% for week in month_cal %}
<tr>
{% for day in week %}
<td>
{% if day == 0 %}
-
{% else %}
{{ day }}
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<a href="{% url 'calendar:calendar' prev_year prev_month %}">previous</a>
<a href="{% url 'calendar:calendar' next_year next_month %}">next</a>
{% endblock %}
我能够成功地遍历所有事件并遍历日历中的所有日期。但是,我希望事件在适当的日期显示在日历中。
我建议在您的上下文中添加 {day_of_month: events}
的映射,而不是整个月所有事件的列表。这样,在构建模板时,您无需遍历每个月的每一天的所有事件。
这是一个示例实现:
views.py
from collections import defaultdict
...
def Cal(request, year, month):
...
events = Event.objects.filter(when__year=year, when__month=month)
event_days = defaultdict(list)
for event in events:
event_days[event.when.day].append(event)
return render(request, "cal/calendar.html", {
"month_cal": month_cal,
"prev_month": prev_month,
"next_month": next_month,
"prev_year": prev_year,
"next_year": next_year,
"event_days": event_days,
})
接下来,您需要 include a dict lookup template filter 在您的项目中。 (有关实施,请参阅相关问题。)
现在,当您循环浏览日历时,您可以轻松地按天访问事件:
calendar.html
...
{% for week in month_cal %}
<tr>
{% for day in week %}
<td>
{% if day == 0 %}
-
{% else %}
{{ day }}
{% for event in event_days|get_item:day %}
{# format the event here #}
{{ event.description }}
{% endfor %}
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
...