Add admin interface and fix some model issues
authorDavid Kerkeslager <kerkeslager@gmail.com>
Fri, 26 Feb 2021 01:04:23 +0000 (20:04 -0500)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Fri, 26 Feb 2021 01:04:23 +0000 (20:04 -0500)
tickle/admin.py
tickle/migrations/0001_initial.py
tickle/migrations/0002_auto_20210225_1949.py [new file with mode: 0644]
tickle/models.py

index 8c38f3f..4484351 100644 (file)
@@ -1,3 +1,19 @@
 from django.contrib import admin
 
-# Register your models here.
+from . import models
+
+class PitchInline(admin.TabularInline):
+    model = models.Pitch
+
+class RouteAdmin(admin.ModelAdmin):
+    inlines = (
+        PitchInline,
+    )
+
+admin.site.register(models.Route, RouteAdmin)
+
+admin.site.register(models.Attempt)
+admin.site.register(models.Boulder)
+admin.site.register(models.BoulderDifficulty)
+admin.site.register(models.RouteDifficulty)
+admin.site.register(models.Todo)
index 7955d21..1e8635c 100644 (file)
@@ -1,4 +1,4 @@
-# Generated by Django 3.1.7 on 2021-02-25 19:26
+# Generated by Django 3.1.7 on 2021-02-25 19:46
 
 from django.conf import settings
 from django.db import migrations, models
@@ -53,6 +53,7 @@ class Migration(migrations.Migration):
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('notes', models.TextField()),
                 ('protection', models.CharField(choices=[('none', 'None'), ('bolts', 'Bolts'), ('gear', 'Gear'), ('pad', 'Pad'), ('tr', 'Top Rope')], max_length=8)),
+                ('style', models.CharField(choices=[('onsight', 'On Sight'), ('flash', 'Flash'), ('project', 'Project'), ('other', 'Other')], max_length=8)),
                 ('boulder', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='todos', to='tickle.boulder')),
                 ('route', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='todos', to='tickle.route')),
                 ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
@@ -62,6 +63,7 @@ class Migration(migrations.Migration):
             name='Pitch',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('order', models.PositiveSmallIntegerField()),
                 ('difficulty', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='pitches', to='tickle.routedifficulty')),
                 ('route', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pitches', to='tickle.route')),
             ],
@@ -75,6 +77,7 @@ class Migration(migrations.Migration):
             name='Attempt',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('date', models.DateField()),
                 ('notes', models.TextField()),
                 ('result', models.CharField(choices=[('send', 'Sent'), ('fall', 'Fall')], max_length=8)),
                 ('prior_knowledge', models.BooleanField(default=True)),
diff --git a/tickle/migrations/0002_auto_20210225_1949.py b/tickle/migrations/0002_auto_20210225_1949.py
new file mode 100644 (file)
index 0000000..1b487b9
--- /dev/null
@@ -0,0 +1,25 @@
+# Generated by Django 3.1.7 on 2021-02-25 19:49
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('tickle', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='boulder',
+            name='mountainproject',
+            field=models.URLField(blank=True, default=''),
+            preserve_default=False,
+        ),
+        migrations.AlterField(
+            model_name='route',
+            name='mountainproject',
+            field=models.URLField(blank=True, default=''),
+            preserve_default=False,
+        ),
+    ]
index 268d7b0..176a4a5 100644 (file)
@@ -17,13 +17,23 @@ class Boulder(models.Model):
         on_delete=models.PROTECT,
         related_name='boulders',
     )
-    mountainproject = models.URLField(null=True)
+    mountainproject = models.URLField(blank=True)
+
+    def __str__(self):
+        return '{} ({})'.format(self.name, self.difficulty)
 
 class BoulderDifficulty(models.Model):
     order = models.PositiveSmallIntegerField()
     name = models.CharField(max_length=8)
 
+    class Meta:
+        ordering = ('order',)
+
+    def __str__(self):
+        return self.name
+
 class Pitch(models.Model):
+    order = models.PositiveSmallIntegerField()
     route = models.ForeignKey(
         'Route',
         on_delete=models.CASCADE,
@@ -35,6 +45,12 @@ class Pitch(models.Model):
         related_name='pitches',
     )
 
+    class Meta:
+        ordering = ('order',)
+
+    def __str__(self):
+        return 'P{} ({})'.format(self.order, self.difficulty)
+
 PROTECTION_STYLE_CHOICES = (
     ('sport', 'Sport'),
     ('toprope', 'Top Rope'),
@@ -44,17 +60,23 @@ PROTECTION_STYLE_CHOICES = (
 class Route(models.Model):
     name = models.CharField(max_length=64)
     protection_style = models.CharField(max_length=8, choices=PROTECTION_STYLE_CHOICES)
-    mountainproject = models.URLField(null=True)
+    mountainproject = models.URLField(blank=True)
 
     # TODO Write test for this
     @property
     def difficulty(self):
         return self.pitches.order_by('-difficulty__order').first().difficulty
 
+    def __str__(self):
+        return '{} ({})'.format(self.name, self.difficulty)
+
 class RouteDifficulty(models.Model):
     order = models.PositiveSmallIntegerField()
     name = models.CharField(max_length=8)
 
+    def __str__(self):
+        return self.name
+
 ATTEMPT_RESULT_CHOICES = (
     ('send', 'Sent'),
     ('fall', 'Fall'),
@@ -70,6 +92,7 @@ PROTECTION_CHOICES = (
 
 class Attempt(models.Model):
     user = models.ForeignKey(User, on_delete=models.CASCADE)
+    date = models.DateField()
     notes = models.TextField()
     boulder = models.ForeignKey('Boulder', null=True, on_delete=models.PROTECT, related_name='attempts')
     route = models.ForeignKey('Route', null=True, on_delete=models.PROTECT, related_name='attempts')
@@ -85,11 +108,13 @@ class Attempt(models.Model):
             ),
         )
 
+        ordering = ('date',)
+
 STYLE_CHOICES = (
     ('onsight', 'On Sight'),
     ('flash', 'Flash'),
-    ('complete', 'Complete'),
-    ('project', 'project'),
+    ('project', 'Project'),
+    ('other', 'Other'),
 )
 
 class Todo(models.Model):
@@ -98,6 +123,7 @@ class Todo(models.Model):
     protection = models.CharField(max_length=8, choices=PROTECTION_CHOICES)
     boulder = models.ForeignKey('Boulder', null=True, on_delete=models.PROTECT, related_name='todos')
     route = models.ForeignKey('Route', null=True, on_delete=models.PROTECT, related_name='todos')
+    style = models.CharField(max_length=8, choices=STYLE_CHOICES)
 
     class Meta:
         constraints = (
@@ -106,3 +132,15 @@ class Todo(models.Model):
                 name='todo_boulder_xor_route',
             ),
         )
+
+        ordering = ('route__name',)
+
+    def __str__(self):
+        if self.boulder:
+            climb = self.boulder
+        elif self.route:
+            climb = self.route
+        else:
+            raise Exception()
+
+        return '{} {}'.format(self.style, climb)