如何在Django中组合查询集来显示日历事件?

时间:2016-04-16 06:57:26

标签: django events calendar django-queryset

我正在尝试创建一个日历,其中包含在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 %}

我成功地遍历所有事件并循环遍历日历中的所有日期。但是,我希望事件在适当的日期显示在日历中。

1 个答案:

答案 0 :(得分:1)

我建议在您的上下文中添加{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 %}

...