Add weight record modeling
[climbing.kerkeslager.com] / src / climbing / models.py
index 71a8362..14c728e 100644 (file)
@@ -1,3 +1,221 @@
+from django.contrib.auth.models import User
 from django.db import models
 
-# Create your models here.
+class Area(models.Model):
+    name = models.CharField(max_length=64)
+    notes = models.TextField(blank=True, null=True)
+
+    def __str__(self):
+        return self.name
+
+    @property
+    def sub_areas(self):
+        crags = iter(self.crags.order_by('name'))
+        clusters = iter(self.clusters.order_by('name'))
+
+        try:
+            crag = next(crags)
+        except StopIteration:
+            crag = None
+
+        try:
+            cluster = next(clusters)
+        except StopIteration:
+            cluster = None
+
+        while crag and cluster:
+            if crag.name < cluster.name:
+                yield crag
+                try:
+                    crag = next(crags)
+                except:
+                    crag = None
+            else:
+                yield cluster
+                try:
+                    cluster = next(clusters)
+                except:
+                    cluster = None
+
+        while crag:
+            yield crag
+            try:
+                crag = next(crags)
+            except:
+                crag = None
+
+        while cluster:
+            yield cluster
+            try:
+                cluster = next(clusters)
+            except:
+                cluster = None
+
+class Crag(models.Model):
+    area = models.ForeignKey(
+        Area,
+        on_delete=models.CASCADE,
+        related_name='crags',
+    )
+    name = models.CharField(max_length=64)
+    notes = models.TextField(blank=True, null=True)
+
+    def __str__(self):
+        return self.name
+
+class Route(models.Model):
+    area = models.ForeignKey(
+        Crag,
+        on_delete=models.CASCADE,
+        related_name='routes',
+    )
+    name = models.CharField(max_length=64)
+    notes = models.TextField(blank=True, null=True)
+
+    def __str__(self):
+        return self.name
+
+ROUTE_DIFFICULTY_CHOICES = (
+    ('5.0', '5.0'),
+    ('5.1', '5.1'),
+    ('5.2', '5.2'),
+    ('5.3', '5.3'),
+    ('5.4', '5.4'),
+    ('5.5', '5.5'),
+    ('5.6', '5.6'),
+    ('5.6+', '5.6+'),
+    ('5.7', '5.7'),
+    ('5.7+', '5.7+'),
+    ('5.8', '5.8'),
+    ('5.8+', '5.8+'),
+    ('5.9-', '5.9-'),
+    ('5.9', '5.9'),
+    ('5.9+', '5.9+'),
+    ('5.10a', '5.10a'),
+    ('5.10b', '5.10b'),
+    ('5.10c', '5.10c'),
+    ('5.10d', '5.10d'),
+    ('5.11a', '5.11a'),
+    ('5.11b', '5.11b'),
+    ('5.11c', '5.11c'),
+    ('5.11d', '5.11d'),
+    ('5.12a', '5.12a'),
+    ('5.12b', '5.12b'),
+    ('5.12c', '5.12c'),
+    ('5.12d', '5.12d'),
+    ('5.13a', '5.13a'),
+    ('5.13b', '5.13b'),
+    ('5.13c', '5.13c'),
+    ('5.13d', '5.13d'),
+    ('5.14a', '5.14a'),
+    ('5.14b', '5.14b'),
+    ('5.14c', '5.14c'),
+    ('5.14d', '5.14d'),
+    ('5.15a', '5.15a'),
+    ('5.15b', '5.15b'),
+    ('5.15c', '5.15c'),
+    ('5.15d', '5.15d'),
+)
+
+SAFETY_CHOICES = (
+    ('G', 'G'),
+    ('PG', 'PG'),
+    ('PG13', 'PG13'),
+    ('R', 'R'),
+    ('X', 'X'),
+)
+
+class Pitch(models.Model):
+    route = models.ForeignKey(
+        Route,
+        on_delete=models.CASCADE,
+        related_name='pitches',
+    )
+    name = models.CharField(max_length=64, null=True)
+    difficulty = models.CharField(max_length=5, choices=ROUTE_DIFFICULTY_CHOICES)
+    safety = models.CharField(max_length=4, choices=SAFETY_CHOICES)
+    notes = models.TextField(blank=True, null=True)
+
+    def __str__(self):
+        if self.name:
+            return '{} ({})'.format(self.name, self.difficulty)
+        return 'Pitch ({})'.format(self.difficulty)
+
+class Cluster(models.Model):
+    area = models.ForeignKey(
+        Area,
+        on_delete=models.CASCADE,
+        related_name='clusters',
+    )
+    name = models.CharField(max_length=64)
+    notes = models.TextField(blank=True, null=True)
+
+    def __str__(self):
+        return self.name
+
+class Boulder(models.Model):
+    cluster = models.ForeignKey(
+        Cluster,
+        on_delete=models.CASCADE,
+        related_name='boulders',
+    )
+    name = models.CharField(max_length=64)
+    notes = models.TextField(blank=True, null=True)
+
+    def __str__(self):
+        return self.name
+
+BOULDER_DIFFICULTY_CHOICES = (
+    ('V0', 'V0'),
+    ('V1', 'V1'),
+    ('V2', 'V2'),
+    ('V3', 'V3'),
+    ('V4', 'V4'),
+    ('V5', 'V5'),
+    ('V6', 'V6'),
+    ('V7', 'V7'),
+    ('V8', 'V8'),
+    ('V9', 'V9'),
+    ('V10', 'V10'),
+    ('V11', 'V11'),
+    ('V12', 'V12'),
+    ('V13', 'V13'),
+    ('V14', 'V14'),
+    ('V15', 'V15'),
+    ('V16', 'V16'),
+    ('V17', 'V17'),
+)
+
+class Problem(models.Model):
+    boulder = models.ForeignKey(
+        Boulder,
+        on_delete=models.CASCADE,
+        related_name='problems',
+    )
+    name = models.CharField(max_length=64)
+    difficulty = models.CharField(max_length=3, choices=BOULDER_DIFFICULTY_CHOICES)
+    safety = models.CharField(max_length=4, choices=SAFETY_CHOICES)
+    notes = models.TextField(blank=True, null=True)
+
+    def __str__(self):
+        return '{} ({})'.format(self.name, self.difficulty)
+
+class RouteTodo(models.Model):
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    route = models.ForeignKey(Route, on_delete=models.CASCADE)
+
+class ProblemTodo(models.Model):
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    problem = models.ForeignKey(Problem, on_delete=models.CASCADE)
+
+class RouteTick(models.Model):
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    route = models.ForeignKey(Route, on_delete=models.CASCADE)
+    timestamp = models.DateTimeField()
+    notes = models.TextField(blank=True, null=True)
+
+class ProblemTick(models.Model):
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    problem = models.ForeignKey(Problem, on_delete=models.CASCADE)
+    timestamp = models.DateTimeField()
+    notes = models.TextField(blank=True, null=True)