from django.conf import settings from django.db import models from django.db.models import F, Q from django.urls import reverse class Venue(models.Model): name = models.CharField(max_length=80) code = models.SlugField(unique=True) access_note = models.CharField(max_length=160, blank=True, default="") def __str__(self): return self.name class WorkshopQuerySet(models.QuerySet): def public(self): return self.filter(published=True) class Workshop(models.Model): title = models.CharField(max_length=100) slug = models.SlugField(unique=True) venue = models.ForeignKey(Venue, on_delete=models.PROTECT, related_name="workshops") starts_at = models.DateTimeField() capacity = models.PositiveIntegerField() remaining = models.PositiveIntegerField() published = models.BooleanField(default=False) objects = WorkshopQuerySet.as_manager() class Meta: ordering = ["starts_at", "pk"] constraints = [ models.CheckConstraint(condition=Q(capacity__gte=1), name="capacity_positive"), models.CheckConstraint(condition=Q(remaining__lte=F("capacity")), name="remaining_within_capacity"), ] def __str__(self): return self.title def get_absolute_url(self): return reverse("workshops:detail", kwargs={"slug": self.slug}) class Reservation(models.Model): workshop = models.ForeignKey(Workshop, on_delete=models.PROTECT, related_name="reservations") user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT) seats = models.PositiveSmallIntegerField() created_at = models.DateTimeField(auto_now_add=True) class Meta: constraints = [ models.UniqueConstraint(fields=["workshop", "user"], name="one_reservation_per_user"), models.CheckConstraint(condition=Q(seats__gte=1, seats__lte=4), name="seats_one_to_four"), ]