DRF: Making a single put request update several objects at once

Viewed 85

I'm creating a timesheet app for logging user tasks. This is the Timesheet model:

class Timesheet(models.Model):
    date = models.ForeignKey(
        'Attendance',
        on_delete=models.CASCADE
    )
    start_time = models.TimeField()
    duration = models.DurationField()
    task = models.CharField(max_length=20)

I need to a way to update a task through a PUT request after several tasks had been created. The problem is that the start_time of a task depends on the start_time and duration of the previous tasks. So if I want to change the duration of a task, I'll need to change the start_time of all the tasks that came after it.

How do I achieve this? I'm currently using the generic view class RetrieveUpdateDestroyAPIView for the TimesheetDetail view. Should I override the put() or update() method?

1 Answers

I followed @Klim Bim original suggestion and decided to override the save() method in the Timesheet model, since I would like to ensure consistency at every creation/update.

def save(self, *args, **kwargs):
    super().save(*args, **kwargs)

    queryset = Timesheet.objects.filter(
        date=self.date,
        start_time__gt=self.start_time
    ).order_by('start_time')

    corrected_time = (
        datetime.combine(date.today(), self.start_time) + self.duration
    ).time()

    for obj in queryset:
        obj.time = corrected_time
        corrected_time = (
            datetime.combine(date.today(), obj.start_time) + obj.duration
        ).time()
        super(Timesheet, obj).save()
Related