Django 验证时隙

Django validating time slot

这是我的模型,用于存储新预订时特定时间的可用性

class TimeSlot(models.Model):
day = models.ForeignKey(
    Day,
    on_delete=models.CASCADE,
    related_name="time"
)
booking = models.ForeignKey(
    Booking,
    on_delete=models.CASCADE,
    related_name="time"
)
start_hour = models.TimeField()
end_hour = models.TimeField()

class Meta:
    unique_together = [('end_hour', 'start_hour',)]


def clean(self):
    pass

目前它允许预订,即使那些在 end_hour 和 start_hour 方面被认为是重复的。我想阻止空位,这样就不会在已经预订的范围之间放置新的预订。

有谁知道如何使用范围吗?

我认为问题是允许添加属于现有时间范围内的 start_hourend_hour。当然 unique_together 约束不能处理这个,因为它只处理范围内的唯一性而不是唯一性。相反,您可以覆盖您的模型 clean 方法并在那里执行此验证:

from django.db.models import Q
from django.core.exceptions import ValidationError


class TimeSlot(models.Model):
    day = models.ForeignKey(
        Day,
        on_delete=models.CASCADE,
        related_name="time"
    )
    booking = models.ForeignKey(
        Booking,
        on_delete=models.CASCADE,
        related_name="time"
    )
    start_hour = models.TimeField()
    end_hour = models.TimeField()
    
    class Meta:
        unique_together = [('end_hour', 'start_hour',)]
    
    
    def clean(self):
        start_hour_in_range = Q(start_hour__lte=self.start_hour, end_hour__gte=self.start_hour)
        end_hour_in_range = Q(start_hour__lte=self.end_hour, end_hour__gte=self.end_hour)
        # Queryset that finds all clashing timeslots with the same day
        queryset = self._meta.default_manager.filter(start_hour_in_range | end_hour_in_range, day=self.day)
        if self.pk:
            queryset = queryset.exclude(pk=self.pk) # Exclude this object if it is already saved to the database
        if queryset.exists():
            raise ValidationError('An existing timeslot clashes with the given one!')

接下来,如果您使用的是 ModelForm,此方法将被自动调用,否则您可以调用 instance.full_clean(),它将调用此方法和模型上的所有其他清洁方法(clean_fieldsvalidate_unique).