reservations: Add generated Reservation.timespan field and use it for filtering
This commit is contained in:
parent
7101e90f8f
commit
7d5fd08855
24
reservations/migrations/0003_reservation_timespan.py
Normal file
24
reservations/migrations/0003_reservation_timespan.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Generated by Django 5.1.1 on 2024-09-09 21:32
|
||||
|
||||
import django.contrib.postgres.fields.ranges
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("reservations", "0002_externalreservation"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="reservation",
|
||||
name="timespan",
|
||||
field=models.GeneratedField(
|
||||
db_persist=True,
|
||||
expression=models.Func(
|
||||
models.F("start"), models.F("end"), function="tstzrange"
|
||||
),
|
||||
output_field=django.contrib.postgres.fields.ranges.DateTimeRangeField(),
|
||||
),
|
||||
),
|
||||
]
|
@ -3,11 +3,13 @@ from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.postgres.fields import DateTimeRangeField
|
||||
from django.db import models
|
||||
from django.db.models import F, Q, QuerySet
|
||||
from django.utils import timezone
|
||||
|
||||
from model_utils.managers import InheritanceQuerySetMixin
|
||||
from psycopg.types.range import Range
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Iterable
|
||||
@ -55,31 +57,32 @@ class ReservationQuerySet(InheritanceQuerySetMixin, QuerySet):
|
||||
Selects events that are after the specified datetime, including
|
||||
overlaps but excluding exactly matching endpoints.
|
||||
"""
|
||||
return self.filter(Q(start__gt=start) | Q(end__gt=start))
|
||||
return self.filter(timespan__overlap=Range(start, None))
|
||||
|
||||
def filter_before(self, end: datetime) -> ReservationQuerySet:
|
||||
"""
|
||||
Selects events that are before the specified datetime, including
|
||||
overlaps but excluding exactly matching endpoints.
|
||||
"""
|
||||
return self.filter(Q(start__lt=end) | Q(end__lt=end))
|
||||
return self.filter(timespan__overlap=Range(None, end))
|
||||
|
||||
def filter_between(self, start: datetime, end: datetime) -> ReservationQuerySet:
|
||||
"""
|
||||
Selects events that are between the specified datetime, including
|
||||
overlaps but excluding exactly matching endpoints.
|
||||
"""
|
||||
return self.filter(
|
||||
Q(start__gt=start, start__lt=end)
|
||||
| Q(end__gt=start, end__lt=end)
|
||||
| (Q(start__lt=start) & Q(end__gt=end))
|
||||
)
|
||||
return self.filter(timespan__overlap=Range(start, end))
|
||||
|
||||
|
||||
class Reservation(models.Model):
|
||||
resources = models.ManyToManyField(Resource, blank=True)
|
||||
start = models.DateTimeField()
|
||||
end = models.DateTimeField()
|
||||
timespan = models.GeneratedField(
|
||||
expression=models.Func(F("start"), F("end"), function="tstzrange"),
|
||||
output_field=DateTimeRangeField(),
|
||||
db_persist=True,
|
||||
)
|
||||
google_calendar_event_id = models.CharField(
|
||||
max_length=1024, null=True, blank=True, unique=True
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user