reservations: Add generated Reservation.timespan field and use it for filtering
This commit is contained in:
parent
d25f1e673a
commit
d19b2d19fb
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 typing import TYPE_CHECKING
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.contrib.postgres.fields import DateTimeRangeField
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import F, Q, QuerySet
|
from django.db.models import F, Q, QuerySet
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from model_utils.managers import InheritanceQuerySetMixin
|
from model_utils.managers import InheritanceQuerySetMixin
|
||||||
|
from psycopg.types.range import Range
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
@ -55,31 +57,32 @@ class ReservationQuerySet(InheritanceQuerySetMixin, QuerySet):
|
|||||||
Selects events that are after the specified datetime, including
|
Selects events that are after the specified datetime, including
|
||||||
overlaps but excluding exactly matching endpoints.
|
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:
|
def filter_before(self, end: datetime) -> ReservationQuerySet:
|
||||||
"""
|
"""
|
||||||
Selects events that are before the specified datetime, including
|
Selects events that are before the specified datetime, including
|
||||||
overlaps but excluding exactly matching endpoints.
|
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:
|
def filter_between(self, start: datetime, end: datetime) -> ReservationQuerySet:
|
||||||
"""
|
"""
|
||||||
Selects events that are between the specified datetime, including
|
Selects events that are between the specified datetime, including
|
||||||
overlaps but excluding exactly matching endpoints.
|
overlaps but excluding exactly matching endpoints.
|
||||||
"""
|
"""
|
||||||
return self.filter(
|
return self.filter(timespan__overlap=Range(start, end))
|
||||||
Q(start__gt=start, start__lt=end)
|
|
||||||
| Q(end__gt=start, end__lt=end)
|
|
||||||
| (Q(start__lt=start) & Q(end__gt=end))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Reservation(models.Model):
|
class Reservation(models.Model):
|
||||||
resources = models.ManyToManyField(Resource, blank=True)
|
resources = models.ManyToManyField(Resource, blank=True)
|
||||||
start = models.DateTimeField()
|
start = models.DateTimeField()
|
||||||
end = 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(
|
google_calendar_event_id = models.CharField(
|
||||||
max_length=1024, null=True, blank=True, unique=True
|
max_length=1024, null=True, blank=True, unique=True
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user