Prevent DateRangeField overlap in model?

224 views
Skip to first unread message

Brylie Christopher Oxley

unread,
Oct 1, 2017, 5:53:53 PM10/1/17
to django-d...@googlegroups.com
Now that Django supports the DateRangeField, is there a 'Pythonic' way to prevent records from having overlapping date ranges?

# Hypothetical use case
One hypothetical use case would be a booking system, where you don't want people to book the same resource at the same time.

# Hypothetical example code
<!-- language: lang-py -->

class Booking(models.model):
# The resource to be reserved
resource = models.ForeignKey('Resource')
# When to reserve the resource
date_range = models.DateRangeField()

class Meta:
unique_together = ('resource', 'date_range',)

This might have the effect of adding an exclusion constraint on the underlying table:
https://www.postgresql.org/docs/9.3/static/sql-createtable.html#SQL-CREATETABLE-EXCLUDE
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

Laurence Sonnenberg

unread,
Oct 3, 2017, 10:32:04 AM10/3/17
to Django developers (Contributions to Django itself)
A pythonic way to do this would be extremely useful if it existed. As you suggested, I did this using a sql exclusion constraint statement on the table and a migration.
 
For example:

000x_your_migration_name.py

 # -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations

SQL = """ALTER TABLE your_table DROP CONSTRAINT IF EXISTS range_overlap_exclusion;
               ALTER TABLE your_table ADD CONSTRAINT range_overlap_exclusion
               EXCLUDE USING gist (resource WITH =, date_range WITH &&);"""


class Migration(migrations.Migration):

    dependencies = [
        ('module_name', '000x_previous_migration'),
    ]

    operations = [migrations.RunSQL(sql=SQL, reverse_sql=migrations.RunSQL.noop), ]

Ian Foote

unread,
Oct 4, 2017, 11:09:00 AM10/4/17
to django-d...@googlegroups.com
Hi Brylie, Laurence,

I think it should be possible to do this using my Check Constraints work
(https://github.com/django/django/pull/7615) or something built on top
of it.

I plan to get this work into shape so it can land in Django 2.1.

I hope this helps,
Ian
> --
> You received this message because you are subscribed to the Google
> Groups "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-develop...@googlegroups.com
> <mailto:django-develop...@googlegroups.com>.
> To post to this group, send email to django-d...@googlegroups.com
> <mailto:django-d...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/f595965d-8646-40f8-8637-f5011ba8f535%40googlegroups.com
> <https://groups.google.com/d/msgid/django-developers/f595965d-8646-40f8-8637-f5011ba8f535%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages