Как сделать так, чтобы события между начальным и конечным временем отображались в моем календаре

Я использую учебник, который нашел в Интернете... и он в основном работает... Я застрял, когда пытаюсь просмотреть список событий и показать их на ежедневной основе. Если у меня есть событие, которое начинается 1 июня и заканчивается 5 июня... я хотел бы иметь возможность показать это событие 2 июня в моем списке, а также 3 и 4 июня. В настоящее время я могу заставить его сказать, что событие начинается 1 июня и заканчивается 5 июня. Я пробовал несколько различных фильтров, используя GTE и LTE, но это, похоже, не помогает.

Вот моя утилита "Календарь"...

class Calendar(HTMLCalendar):
    def __init__(self, year=None, month=None, dropdown=None):
        self.dropdown = dropdown
        self.year = year
        self.month = month
        super(Calendar, self).__init__()

    # formats a day as a td
    # filter events by day
    def formatday(self, day, events):
        events_per_day = events.filter(start_time__day__lte=day, end_time__day__gte=day)
        d = ''
        for event in events_per_day:
            d += f'<li> {event.get_html_url} </li>'

        if day != 0:
            return f"<td><span class='date'>{day}</span><ul> {d} </ul></td>"
        return '<td></td>'

    # formats a week as a tr
    def formatweek(self, theweek, events):
        week = ''
        for d, weekday in theweek:
            week += self.formatday(d, events)
        return f'<tr> {week} </tr>'

    # formats a month as a table
    # filter events by year and month
    def formatmonth(self, withyear=True):
        events = VacationRequest.objects.filter(vacation_calendar=self.dropdown,start_time__year=self.year,start_time__month=self.month).order_by('start_time')
        cal = f'<table border="0" cellpadding="0" cellspacing="0" class="calendar">\n'
        cal += f'{self.formatmonthname(self.year, self.month, withyear=withyear)}\n'
        cal += f'{self.formatweekheader()}\n'
        for week in self.monthdays2calendar(self.year, self.month):
            cal += f'{self.formatweek(week, events)}\n'
        cal += f'</table>\n'
        cal += f'<h1 class="title">Vacation Schedule For {self.formatmonthname(self.year, self.month, withyear=withyear)}</h1>\n'
        return cal

Вот мое мнение...

class VacationRequestCalendarView(generic.ListView):
    model = VacationRequest
    template_name = 'vacation_request_calendar_view.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        dropdown = (self.request.GET.get("dropdown", None))
        d = get_date(self.request.GET.get('month', None))
        cal = Calendar(d.year, d.month, dropdown)
        cal.setfirstweekday(calendar.SUNDAY)
        html_cal = cal.formatmonth(withyear=True)
        vacation_calendar = VacationCalendar.objects.get(id=self.request.GET.get("dropdown", None))
        vacation_calendar_requests = VacationRequest.objects.filter(start_time__year = d.year,start_time__month = d.month)
        context['calendar'] = mark_safe(html_cal)
        context['dropdown'] = dropdown
        context['next_month'] = next_month(d)
        context['prev_month'] = prev_month(d)
        context['vacation_calendar_requests'] = vacation_calendar_requests
        context['vacation_calendar'] = vacation_calendar
        return context

    def get_object(self, queryset=None):
        return get_object_or_404(VacationCalendar, id=self.request.GET.get("dropdown"))       

def get_date(req_month):
    if req_month:
        year, month = (int(x) for x in req_month.split('-'))
        return date(year, month, day=1)
    return datetime.today()

def prev_month(d):
    first = d.replace(day=1)
    prev_month = first - timedelta(days=1)
    month = 'month=' + str(prev_month.year) + '-' + str(prev_month.month)
    return month

def next_month(d):
    days_in_month = calendar.monthrange(d.year, d.month)[1]
    last = d.replace(day=days_in_month)
    next_month = last + timedelta(days=1)
    month = 'month=' + str(next_month.year) + '-' + str(next_month.month)
    return month

А вот моя логика шаблонов Django...

 {% if vacation_calendar_requests %}

    {% for request in vacation_calendar_requests %}

      <div class="leftwidth87">
      {% ifchanged request.start_time|date:"M d, Y" %}
      <h2>{{ request.start_time|date:"M d, Y" }}</h2>
       {% endifchanged %}
        <div>
          <h2><a href="{% url 'VacationRequests:vacation_request_detail' pk=request.pk %}">{{ request.vacation_request_name }}
          {{ request.start_time }} -
          {{ request.end_time }}</a></h2>
        </div>
      </div>

    {% endfor ifchanged %}

  {% else %}

    <div class="title">
      <h2>No Vacation Scheduled</h2>
    </div>

  {% endif %}

Код выше правильно отображает события, которые охватывают несколько дней в календаре... Это связано с функцией formatday. Я вижу, как она правильно фильтрует события по дням... Я просто не могу понять, как сделать то же самое, когда я пытаюсь вывести события по дням через логику моего шаблона.

Я понимаю, что я нахожу только 2 события с помощью моего шаблонного цикла... как я это делаю... но как я могу просмотреть цикл и найти события по дням, а не только по их диапазону (время начала и время окончания?)

Любые мысли или идеи будут высоко оценены!!!!

Существует библиотека под названием datetimerange . Когда создается событие, вы можете получить время начала и окончания даты (что вы уже делаете), передать его в функцию DateTimeRange и сохранить как строку в DB.

Когда вы получите событие обратно. Вы можете снова получить значения времени даты. Вот кусок кода из документации библиотеки:

import datetime
from datetimerange import DateTimeRange

time_range = DateTimeRange("2015-01-01T00:00:00+0900", "2015-01-04T00:00:00+0900")
for value in time_range.range(datetime.timedelta(days=1)):
    print(value)

Я бы вычислил продолжительность (количество дней), а затем использовал эту продолжительность как количество раз для цикла. Затем, чтобы получить дату для каждого дня продолжительности, я бы использовал переменную счетчика (возможно, перечислитель) и добавил бы ее к дате. Например, если счетчик равен 2, то я добавлю 2 дня к начальной дате, чтобы получить текущую дату в цикле.

Надеемся, это даст вам представление.

Используя ваш пример, добавьте это к вашему представлению:

from datetime import timedelta, date

def daterange(date1, date2):
    for n in range(int ((date2 - date1).days)+1):
    yield date1 + timedelta(n)
start_dt = date(2015, 12, 20) 
end_dt = date(2016, 1, 11) 
dates = [date for date in daterange(start_dt, end_dt)] 
Вернуться на верх