Как использовать HTMLCalendar

Я использую Django, и я использую модуль HTMLCalendar для печати календаря на странице. В настоящее время приведенный ниже код работает нормально, но когда дата между 'from date' и 'to date' больше 2 дней, я хочу выразить это в одной строке вместо того, чтобы добавлять событие к каждой дате, принадлежащей периоду. Сколько бы я не искал, я не смог найти ни одного поста с подобными трудностями, и я не могу решить их самостоятельно уже несколько дней. Помогите!

[models.py]

class Leave(models.Model):
    title = models.CharField(max_length=50, blank=True, null=True)
    from_date = models.DateField(blank=True, null=True)
    end_date = models.DateField(blank=True, null=True)
    memo = models.TextField(blank=True, null=True)
    user = models.ForeignKey(User, on_delete=models.SET_NULL, 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'<div class="event-title" colspan="{self.end_date - self.from_date}"><a href="{url}" style="color:black;"> {self.title} </a></div>'

[forms.py]

class LeaveForm(ModelForm):
  class Meta:
    model = Leave
    # datetime-local is a HTML5 input type, format to make date time show on fields
    widgets = {
      'from_date': DateInput(attrs={'type': 'datetime', 'class': 'datepicker', 'autocomplete': 'off'}, format='%Y-%m-%d'),
      'end_date': DateInput(attrs={'type': 'datetime', 'class': 'datepicker', 'autocomplete': 'off'}, format='%Y-%m-%d'),
      'user': Select(attrs={"disabled": 'disabled'}),
    }
    fields = ['title', 'from_date', 'end_date', 'memo', 'user']

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

[utils.py]

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

# formats a day as a td
# filter events by day
def formatday(self, day, events, next_visit):
    events_per_day = events.filter(user=self.user).annotate(end_date_month=ExtractMonth('end_date'))\
        .filter(Q(from_date__day=day, end_date__isnull=True) |
                Q(from_date__day__lte=day, end_date__day__gte=day) |
                (Q(from_date__day__lte=day, from_date__year=self.year, from_date__month=self.month) &
                 ~Q(from_date__month=F('end_date_month'))) |
                (Q(end_date__day__gte=day, end_date__year=self.year, end_date__month=self.month) &
                 ~Q(from_date__month=F('end_date_month'))))

    next_visit_per_day = next_visit.filter(next_visit__day=day, next_visit__year=self.year, next_visit__month=self.month, assignment__curr_crc=self.user.first_name)

    d = ''
    for event in events_per_day:
        d += f'{event.get_html_url}'

    for next_visit in next_visit_per_day:
        d += f'{next_visit.get_html_url}'

    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, next_visit):
    week = ''
    for d, weekday in theweek:
        week += self.formatday(d, events, next_visit)
    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(is_deleted=False)\
                          .filter(Q(from_date__year=self.year, from_date__month=self.month) |
                                  Q(end_date__year=self.year, end_date__month=self.month))

    next_visit = Feedback.objects.filter(assignment__is_deleted=0, next_visit__isnull=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, next_visit)}\n'
    return cal

[views.py]

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)
        first_name = self.request.user

        # Instantiate our calendar class with today's year and date
        cal = Calendar(d.year, d.month, first_name)
       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()

def prev_month(d):
    first = d.replace(day=1)
    prev_month = first - datetime.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 + datetime.timedelta(days=1)
    month = 'month=' + str(next_month.year) + '-' + str(next_month.month)
    return month

def leave(request, leave_id=None):
    instance = Leave()
    if leave_id:
        instance = get_object_or_404(Leave, pk=leave_id)
    else:
        instance = Leave()
    instance
    form = LeaveForm(request, request.POST or None, instance=instance)
    if request.POST and form.is_valid():
        form = form.save(commit=False)
        form.user = request.user
       form.save()
        return HttpResponseRedirect(reverse('leave:calendar'))
    return render(request, 'pages/leave/leave_add.html', {'form': form})


@login_required()
def leave_delete(request, leave_id):
    leave = Leave.objects.get(pk=leave_id)
    leave.is_deleted = True
    leave.save()
    return HttpResponseRedirect(f'/leave/calendar/')
Вернуться на верх