2016-04-16 1 views
0

Я пытаюсь создать календарь с событиями, показывая дату, когда и событие было создано в модели Event вместе с DateTimeField.Как объединить запросы в Django для отображения событий календаря?

Вот мой код: 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

Предлагаю добавить в свой контекст сопоставление {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 %} 

... 
+0

Спасибо. Я пытаюсь понять, что это за строка 'event_days = defaultdict (list)'. Откуда возникает переменная 'list'? – MiniGunnR

+0

['defaultdict'] (https://docs.python.org/3/library/collections.html#collections.defaultdict) принимает заводскую функцию как конструктор. ['list'] (https://docs.python.org/3/library/functions.html#func-list) является встроенным типом. Поэтому 'defaultdict (list)' будет автоматизировать создание списка при вызове 'append()'. Подробнее см. Http://stackoverflow.com/questions/5900578/how-does-collections-defaultdict-work. – keithb

Смежные вопросы