83d437f1e6b1c10f2dff565829c21028c50341ec
[climbing.kerkeslager.com] / src / climbing / models.py
1 from django.contrib.auth.models import User
2 from django.db import models
3
4 from core import utils
5
6 class Area(models.Model):
7     name = models.CharField(max_length=64)
8     notes = models.TextField(blank=True, null=True)
9
10     def __str__(self):
11         return self.name
12
13     @property
14     def sub_areas(self):
15         return utils.merge(
16             self.crags.order_by('name'),
17             self.clusters.order_by('name'),
18             'name',
19         )
20
21 class Crag(models.Model):
22     area = models.ForeignKey(
23         Area,
24         on_delete=models.CASCADE,
25         related_name='crags',
26     )
27     name = models.CharField(max_length=64)
28     notes = models.TextField(blank=True, null=True)
29
30     def __str__(self):
31         return self.name
32
33 class Route(models.Model):
34     area = models.ForeignKey(
35         Crag,
36         on_delete=models.CASCADE,
37         related_name='routes',
38     )
39     name = models.CharField(max_length=64)
40     mountain_project = models.URLField(blank=True, null=True)
41     notes = models.TextField(blank=True, null=True)
42
43     def __str__(self):
44         return self.name
45
46 ROUTE_DIFFICULTY_CHOICES = (
47     ('5.0', '5.0'),
48     ('5.1', '5.1'),
49     ('5.2', '5.2'),
50     ('5.3', '5.3'),
51     ('5.4', '5.4'),
52     ('5.5', '5.5'),
53     ('5.6', '5.6'),
54     ('5.6+', '5.6+'),
55     ('5.7', '5.7'),
56     ('5.7+', '5.7+'),
57     ('5.8', '5.8'),
58     ('5.8+', '5.8+'),
59     ('5.9-', '5.9-'),
60     ('5.9', '5.9'),
61     ('5.9+', '5.9+'),
62     ('5.10a', '5.10a'),
63     ('5.10b', '5.10b'),
64     ('5.10c', '5.10c'),
65     ('5.10d', '5.10d'),
66     ('5.11a', '5.11a'),
67     ('5.11b', '5.11b'),
68     ('5.11c', '5.11c'),
69     ('5.11d', '5.11d'),
70     ('5.12a', '5.12a'),
71     ('5.12b', '5.12b'),
72     ('5.12c', '5.12c'),
73     ('5.12d', '5.12d'),
74     ('5.13a', '5.13a'),
75     ('5.13b', '5.13b'),
76     ('5.13c', '5.13c'),
77     ('5.13d', '5.13d'),
78     ('5.14a', '5.14a'),
79     ('5.14b', '5.14b'),
80     ('5.14c', '5.14c'),
81     ('5.14d', '5.14d'),
82     ('5.15a', '5.15a'),
83     ('5.15b', '5.15b'),
84     ('5.15c', '5.15c'),
85     ('5.15d', '5.15d'),
86 )
87
88 SAFETY_CHOICES = (
89     ('G', 'G'),
90     ('PG', 'PG'),
91     ('PG13', 'PG13'),
92     ('R', 'R'),
93     ('X', 'X'),
94 )
95
96 class Pitch(models.Model):
97     route = models.ForeignKey(
98         Route,
99         on_delete=models.CASCADE,
100         related_name='pitches',
101     )
102     name = models.CharField(max_length=64, null=True)
103     difficulty = models.CharField(max_length=5, choices=ROUTE_DIFFICULTY_CHOICES)
104     safety = models.CharField(max_length=4, choices=SAFETY_CHOICES)
105     notes = models.TextField(blank=True, null=True)
106
107     def __str__(self):
108         if self.name:
109             return '{} ({})'.format(self.name, self.difficulty)
110         return 'Pitch ({})'.format(self.difficulty)
111
112 class Cluster(models.Model):
113     area = models.ForeignKey(
114         Area,
115         on_delete=models.CASCADE,
116         related_name='clusters',
117     )
118     name = models.CharField(max_length=64)
119     notes = models.TextField(blank=True, null=True)
120
121     def __str__(self):
122         return self.name
123
124 class Boulder(models.Model):
125     cluster = models.ForeignKey(
126         Cluster,
127         on_delete=models.CASCADE,
128         related_name='boulders',
129     )
130     name = models.CharField(max_length=64)
131     notes = models.TextField(blank=True, null=True)
132
133     def __str__(self):
134         return self.name
135
136 BOULDER_DIFFICULTY_CHOICES = (
137     ('V0', 'V0'),
138     ('V1', 'V1'),
139     ('V2', 'V2'),
140     ('V3', 'V3'),
141     ('V4', 'V4'),
142     ('V5', 'V5'),
143     ('V6', 'V6'),
144     ('V7', 'V7'),
145     ('V8', 'V8'),
146     ('V9', 'V9'),
147     ('V10', 'V10'),
148     ('V11', 'V11'),
149     ('V12', 'V12'),
150     ('V13', 'V13'),
151     ('V14', 'V14'),
152     ('V15', 'V15'),
153     ('V16', 'V16'),
154     ('V17', 'V17'),
155 )
156
157 class Problem(models.Model):
158     boulder = models.ForeignKey(
159         Boulder,
160         on_delete=models.CASCADE,
161         related_name='problems',
162     )
163     name = models.CharField(max_length=64)
164     difficulty = models.CharField(max_length=3, choices=BOULDER_DIFFICULTY_CHOICES)
165     safety = models.CharField(max_length=4, choices=SAFETY_CHOICES)
166     mountain_project = models.URLField(blank=True, null=True)
167     notes = models.TextField(blank=True, null=True)
168
169     def __str__(self):
170         return '{} ({})'.format(self.name, self.difficulty)
171
172 class RouteTodo(models.Model):
173     user = models.ForeignKey(User, on_delete=models.CASCADE)
174     route = models.ForeignKey(Route, on_delete=models.CASCADE)
175
176 class ProblemTodo(models.Model):
177     user = models.ForeignKey(User, on_delete=models.CASCADE)
178     problem = models.ForeignKey(Problem, on_delete=models.CASCADE)
179
180 class RouteTick(models.Model):
181     user = models.ForeignKey(User, on_delete=models.CASCADE)
182     route = models.ForeignKey(Route, on_delete=models.CASCADE)
183     timestamp = models.DateTimeField()
184     notes = models.TextField(blank=True, null=True)
185
186 class ProblemTick(models.Model):
187     user = models.ForeignKey(User, on_delete=models.CASCADE)
188     problem = models.ForeignKey(Problem, on_delete=models.CASCADE)
189     timestamp = models.DateTimeField()
190     notes = models.TextField(blank=True, null=True)