Как вывести несколько дней как одно событие с помощью HTMLcalendar

Я использую функцию календаря с помощью модуля HTMLcalendar в django. Я хочу выводить только одно событие в прямой линии на календаре, когда более 2 дней указаны с помощью полей дат 'leave_date' и 'leave_end_date'. В настоящее время, в приведенном ниже коде, событие добавляется в каждый из дней, соответствующих периоду. ex) leave_date: '2021-11-03', leave_end_date: '2021-11-07'

#фильтр событий по дням Я думаю, что эта часть должна быть исправлена, пожалуйста, помогите!

[urls.py]

from django.urls import path
from . import views

app_name = 'leave'
urlpatterns = [
    path('calendar/', views.CalendarView.as_view(), name='calendar'),        # /leave/calendar
    path('calendar/new/', views.leave, name='leave_new'),                    # /leave/calendar/new
    path('calendar/edit/<int:leave_id>/', views.leave, name='leave_edit'),       # /leave/calendar/edit/{}
    path('calendar/delete/<int:leave_id>/', views.leave_delete, name='leave_delete'),     # /leave/calendar/delete/{}
]

[models.py]

from django.db import models
from django.urls import reverse

class Leave(models.Model):
    name = models.CharField(max_length=50, blank=True, null=True)
    leave_date = models.DateField(blank=True, null=True)
    leave_end_date = models.DateField(blank=True, null=True)
    take_over = models.TextField(blank=True, null=True)
    memo = models.TextField(blank=True, null=True)
    is_deleted = models.BooleanField(default=False)
    create_date = models.DateTimeField(auto_now_add=True)
    update_date = models.DateTimeField(auto_now=True)

    @property
    def get_html_url(self):
        url = reverse('leave:leave_edit', args=(self.id,))
        return f'<a href="{url}"> {self.name} </a> <a data-toggle="modal" data-target="#detail_leave_{self.id}">Detail</a>'

[forms.py]

from django.forms import ModelForm, DateInput
from .models import Leave

class LeaveForm(ModelForm):
  class Meta:
    model = Leave
    # datetime-local is a HTML5 input type, format to make date time show on fields
    widgets = {
      'leave_date': DateInput(attrs={'type': 'datetime'}, format='%Y-%m-%d'),
      'leave_end_date': DateInput(attrs={'type': 'datetime'}, format='%Y-%m-%d'),
    }
    fields = ['name', 'leave_date', 'leave_end_date', 'take_over', 'memo']

  def __init__(self, *args, **kwargs):
    super(LeaveForm, self).__init__(*args, **kwargs)
    # input_formats to parse HTML5 datetime-local input to datetime field
    self.fields['leave_date'].input_formats = ('%Y-%m-%d',)
    self.fields['leave_end_date'].input_formats = ('%Y-%m-%d',)

[utils.py]

from datetime import datetime, timedelta
from calendar import HTMLCalendar
from .models import Leave

class Calendar(HTMLCalendar):
    def __init__(self, year=None, month=None):
        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(leave_date__day__lte=day, leave_end_date__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 = Leave.objects.filter(leave_date__year=self.year, leave_date__month=self.month, is_deleted=False)

        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'
        return cal

[views.py]

from django.views import generic
from django.utils.safestring import mark_safe
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, JsonResponse
from django.urls import reverse
from .forms import LeaveForm

from .models import *
from .utils import Calendar
import calendar, datetime
from django.contrib.auth.decorators import login_required

class CalendarView(generic.ListView):
    model = Leave
    template_name = 'pages/leave/leave.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # use today's date for the calendar
        d = get_date(self.request.GET.get('month', None))
        context['prev_month'] = prev_month(d)
        context['next_month'] = next_month(d)

        # Instantiate our calendar class with today's year and date
        cal = Calendar(d.year, d.month)
        cal.setfirstweekday(6)

    # Call the formatmonth method, which returns our calendar as a table
    html_cal = cal.formatmonth(withyear=True)
    context['calendar'] = mark_safe(html_cal)
    context['leave'] = Leave.objects.filter(is_deleted=0)
    return context

def get_date(req_day):
    if req_day:
        year, month = (int(x) for x in req_day.split('-'))
        return datetime.date(year, month, day=1)
    return datetime.datetime.today()
Вернуться на верх