Home > front end >  How to calculate numbers of days between two dates and subtract weekends DJANGO MODELS
How to calculate numbers of days between two dates and subtract weekends DJANGO MODELS

Time:05-22

hope you're all fine!

I have a model called Vacation and I'm struggling with one field: days_requested, this field is the number days from vacation_start and vacation_end, it works and gives me an integer as result. The problem I'm facing now is that I need to subtract the weekends (or not count them).

What I have:

vacation_start = '2022-05-20'
vacation_end = '2022-05-24'
days_requested = 5

What I'm trying to have:

vacation_start = '2022-05-20'
vacation_end = '2022-05-24'
days_requested = 3

#21/05 and 22/05 are weekends

Vacation Models:

class Vacation(models.Model):
    department = models.ForeignKey(
        'departments.Department', on_delete=models.SET_NULL, null=True)
    responsible = models.ForeignKey(
        User, on_delete=models.SET_NULL, null=True, related_name='responsible_vacation')
    status = models.CharField(
        max_length=20, choices=STATUS_CHOICES_VACATIONS, default='open')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    created_by = models.ForeignKey(
        User, on_delete=models.SET_NULL, null=True, related_name='created_by_vacation')
    vacation_start = models.DateField(blank=False)
    vacation_end = models.DateField(blank=False)
    days_requested = property(
        lambda self: (self.vacation_end - self.vacation_start).days   1
    )
    def __str__(self):
        return str(self.created_by.first_name   ' '   self.created_by.last_name)

I have tried:

    days_requested = property(
         lambda self: [(self.vacation_start   datetime.timedelta(days=i)).date()
                      for i in range(0, (self.vacation_end - self.vacation_start)) if (self.vacation_start   datetime.timedelta(days=i)).weekday() not in [5, 6].days()])

But I get the following error:

'datetime.timedelta' object cannot be interpreted as an integer

And as I perform operations with the amount of days asked I need to be able to get an integer.

Thank you all in advance.

CodePudding user response:

UPDATE


class Model:
    days_requested = models.IntegerField(blank=True,null=True)
    
    
      def save(self, *args, **kwargs):
        excluded = (6, 7)
        days = 0
        start_date =self.vacation_start
        while start_date < self.vacation_end:
            if start_date.isoweekday() not in excluded: #if you want to get only weekdays
                days  = 1
                start_date = timedelta(days=1)
         
        self.days_requested=days

        super(YourModel, self).save(*args, **kwargs)


CodePudding user response:

After Elvin's answer I moved the hole logic to my view and set the logic inside form_valid function:

        start = form.instance.vacation_start
        end = form.instance.vacation_end
        delta = end - start
        excluded = (6, 7)
        days = 0
        for i in range(delta.days   1):
            day = start   datetime.timedelta(days=i)
            if day.isoweekday() not in excluded:
                days  = 1
        form.instance.days_requested = days

Thank you all.

  • Related