1 from django.contrib.auth.models import User
2 from django.db import models
6 class Area(models.Model):
7 name = models.CharField(max_length=64)
8 notes = models.TextField(blank=True, null=True)
16 self.crags.order_by('name'),
17 self.clusters.order_by('name'),
21 class Crag(models.Model):
22 area = models.ForeignKey(
24 on_delete=models.CASCADE,
27 name = models.CharField(max_length=64)
28 notes = models.TextField(blank=True, null=True)
33 class Route(models.Model):
34 area = models.ForeignKey(
36 on_delete=models.CASCADE,
37 related_name='routes',
39 name = models.CharField(max_length=64)
40 mountain_project = models.URLField(blank=True, null=True)
41 notes = models.TextField(blank=True, null=True)
44 pitch_count = self.pitches.count()
50 return '{} {}'.format(self.name, self.difficulty_display)
52 return '{} {} ({} pitches)'.format(
54 self.difficulty_display,
62 for pitch in self.pitches.all():
63 diff = max(diff, pitch.difficulty)
68 def difficulty_display(self):
69 return RouteDifficulty(self.difficulty).label
71 class RouteDifficulty(models.IntegerChoices):
87 YDS_5_10a = 15, '5.10a'
88 YDS_5_10b = 16, '5.10b'
89 YDS_5_10c = 17, '5.10c'
90 YDS_5_10d = 18, '5.10d'
91 YDS_5_11a = 19, '5.11a'
92 YDS_5_11b = 20, '5.11b'
93 YDS_5_11c = 21, '5.11c'
94 YDS_5_11d = 22, '5.11d'
95 YDS_5_12a = 23, '5.12a'
96 YDS_5_12b = 24, '5.12b'
97 YDS_5_12c = 25, '5.12c'
98 YDS_5_12d = 26, '5.12d'
99 YDS_5_13a = 27, '5.13a'
100 YDS_5_13b = 28, '5.13b'
101 YDS_5_13c = 29, '5.13c'
102 YDS_5_13d = 30, '5.13d'
103 YDS_5_14a = 31, '5.14a'
104 YDS_5_14b = 32, '5.14b'
105 YDS_5_14c = 33, '5.14c'
106 YDS_5_14d = 34, '5.14d'
107 YDS_5_15a = 35, '5.15a'
108 YDS_5_15b = 36, '5.15b'
109 YDS_5_15c = 37, '5.15c'
110 YDS_5_15d = 38, '5.15d'
120 class Pitch(models.Model):
121 route = models.ForeignKey(
123 on_delete=models.CASCADE,
124 related_name='pitches',
126 name = models.CharField(max_length=64, blank=True, null=True)
127 difficulty = models.PositiveIntegerField(choices=RouteDifficulty.choices)
128 safety = models.CharField(max_length=4, choices=SAFETY_CHOICES)
129 notes = models.TextField(blank=True, null=True)
132 verbose_name_plural = 'pitches'
136 return '{} ({})'.format(self.name, self.difficulty)
137 return 'Pitch ({})'.format(self.difficulty)
139 class Cluster(models.Model):
140 area = models.ForeignKey(
142 on_delete=models.CASCADE,
143 related_name='clusters',
145 name = models.CharField(max_length=64)
146 notes = models.TextField(blank=True, null=True)
151 class Boulder(models.Model):
152 cluster = models.ForeignKey(
154 on_delete=models.CASCADE,
155 related_name='boulders',
157 name = models.CharField(max_length=64)
158 notes = models.TextField(blank=True, null=True)
163 BOULDER_DIFFICULTY_CHOICES = (
184 class Problem(models.Model):
185 boulder = models.ForeignKey(
187 on_delete=models.CASCADE,
188 related_name='problems',
190 name = models.CharField(max_length=64)
191 difficulty = models.CharField(max_length=3, choices=BOULDER_DIFFICULTY_CHOICES)
192 safety = models.CharField(max_length=4, choices=SAFETY_CHOICES)
193 mountain_project = models.URLField(blank=True, null=True)
194 notes = models.TextField(blank=True, null=True)
197 return '{} ({})'.format(self.name, self.difficulty)
199 class RouteTodo(models.Model):
200 user = models.ForeignKey(User, on_delete=models.CASCADE)
201 route = models.ForeignKey(Route, on_delete=models.CASCADE)
203 class ProblemTodo(models.Model):
204 user = models.ForeignKey(User, on_delete=models.CASCADE)
205 problem = models.ForeignKey(Problem, on_delete=models.CASCADE)
207 class RouteTick(models.Model):
208 user = models.ForeignKey(User, on_delete=models.CASCADE)
209 route = models.ForeignKey(Route, on_delete=models.CASCADE)
210 timestamp = models.DateTimeField()
211 notes = models.TextField(blank=True, null=True)
213 class ProblemTick(models.Model):
214 user = models.ForeignKey(User, on_delete=models.CASCADE)
215 problem = models.ForeignKey(Problem, on_delete=models.CASCADE)
216 timestamp = models.DateTimeField()
217 notes = models.TextField(blank=True, null=True)