summaryrefslogtreecommitdiff
path: root/app/birds
diff options
context:
space:
mode:
Diffstat (limited to 'app/birds')
-rw-r--r--app/birds/admin.py52
-rw-r--r--app/birds/models.py149
2 files changed, 191 insertions, 10 deletions
diff --git a/app/birds/admin.py b/app/birds/admin.py
index 77ebc8a..50bd755 100644
--- a/app/birds/admin.py
+++ b/app/birds/admin.py
@@ -1,12 +1,53 @@
from django.contrib import admin
from django.contrib.gis.admin import OSMGeoAdmin
-from birds.models import BirdSighting, BirdAudio, BirdClass, Bird
+from birds.models import BirdSighting, BirdAudio, BirdClass, Bird, APClass, AP, Sighting
from photos.forms import GalleryForm
from utils.util import get_latlon
from utils.widgets import CustomSelectMultiple
+class GalleryFormPlus(GalleryForm):
+ def __init__(self, *args, **kwargs):
+ super(GalleryFormPlus, self).__init__(*args, **kwargs)
+ self.base_fields['seen_by'].widget = CustomSelectMultiple()
+
+ class Meta:
+ model = Sighting
+ fields = '__all__'
+
+
+@admin.register(APClass)
+class APClassAdmin(admin.ModelAdmin):
+ list_display = ('common_name', 'scientific_name', 'kind')
+ list_filter = ('kind',)
+
+
+@admin.register(AP)
+class APAdmin(admin.ModelAdmin):
+ list_display = ('pk', 'common_name', 'scientific_name', 'kind', 'code', 'apclass')
+ list_filter = ('apclass__kind','apclass')
+
+
+@admin.register(Sighting)
+class SightingAdmin(OSMGeoAdmin):
+ form = GalleryFormPlus
+ list_filter = ('seen_by',('location', admin.RelatedOnlyFieldListFilter),)
+ list_display = ('ap', 'location')
+ # options for OSM map Using custom ESRI topo map
+ lat, lon = get_latlon()
+ print(lat, lon)
+ default_lon = lon
+ default_lat = lat
+ default_zoom = 13
+ units = True
+ scrollable = False
+ map_width = 700
+ map_height = 425
+ map_template = 'gis/admin/osm.html'
+ openlayers_url = '/static/admin/js/OpenLayers.js'
+
+
class BirdClassAdmin(admin.ModelAdmin):
list_display = ('common_name', 'scientific_name',)
@@ -19,15 +60,6 @@ class BirdAdmin(admin.ModelAdmin):
list_display = ('pk', 'common_name', 'scientific_name', 'code', 'bird_class')
list_filter = ('bird_class',)
-class GalleryFormPlus(GalleryForm):
- def __init__(self, *args, **kwargs):
- super(GalleryFormPlus, self).__init__(*args, **kwargs)
- self.base_fields['seen_by'].widget = CustomSelectMultiple()
-
- class Meta:
- model = BirdSighting
- fields = '__all__'
-
class BirdSightingAdmin(OSMGeoAdmin):
form = GalleryFormPlus
list_filter = (
diff --git a/app/birds/models.py b/app/birds/models.py
index c73e7d7..5a14786 100644
--- a/app/birds/models.py
+++ b/app/birds/models.py
@@ -17,6 +17,7 @@ def get_upload_path(self, filename):
# from http://aba.org/checklist/codes.html
ABA_CODES = (
+ (0, 'unknown'),
(1, 'regular occurring - common'),
(2, 'regular occurring - less common'),
(3, 'rare'),
@@ -25,6 +26,154 @@ ABA_CODES = (
(6, 'Cannot be found'),
)
+KIND_LIST = (
+ (1, 'Bird'),
+ (2, 'Mammal'),
+ (3, 'Reptile'),
+ (4, 'Amphibian'),
+ (5, 'Plant'),
+)
+
+
+class APClass(models.Model):
+ common_name = models.CharField(max_length=200)
+ scientific_name = models.CharField(max_length=200)
+ kind = models.IntegerField(choices=KIND_LIST, default=1)
+
+ class Meta:
+ verbose_name_plural = 'Animal/Plant Class'
+ ordering = ["kind", "common_name"]
+
+ def __str__(self):
+ return self.common_name
+
+class AP(models.Model):
+ common_name = models.CharField(max_length=200)
+ slug = models.SlugField()
+ scientific_name = models.CharField(max_length=200)
+ code = models.IntegerField(choices=ABA_CODES, default=0)
+ apclass = models.ForeignKey(APClass, on_delete=models.CASCADE)
+ image = models.FileField(upload_to=get_upload_path, null=True, blank=True, help_text="width of high res is 1360px")
+ image_credit = models.CharField(max_length=200, blank=True, null=True)
+
+ def __str__(self):
+ return self.common_name
+
+ def get_image_url(self):
+ return "%s%s" % (settings.IMAGES_URL, self.image.url.split("media")[1][8:])
+
+ def get_absolute_url(self):
+ return reverse("sightings:detail", kwargs={"slug": self.slug})
+
+ def kind(self):
+ return self.apclass.kind
+
+ class Meta:
+ verbose_name_plural = 'Animal/Plant'
+ verbose_name = 'Animal/Plant'
+ ordering = ["common_name", ]
+
+ def save(self, *args, **kwargs):
+ self.slug = slugify(self.common_name[:50])
+ super(AP, self).save(*args, **kwargs)
+
+
+class Sighting(models.Model):
+ ap = models.ForeignKey(AP, on_delete=models.CASCADE)
+ point = models.PointField(blank=True)
+ location = models.ForeignKey(Location, on_delete=models.CASCADE, blank=True, related_name="location_old")
+ date = models.DateTimeField('Date', default=timezone.now)
+ seen_by = models.ManyToManyField(User, related_name="seenby_old")
+ images = models.ManyToManyField(LuxImage, blank=True, related_name="images_old")
+ #audio = models.ManyToManyField(BirdAudio, blank=True)
+
+ class Meta:
+ ordering = ["-date", ]
+
+ @property
+ def state(self):
+ return self.location.state
+
+ @property
+ def country(self):
+ return self.location.state.country
+
+ @property
+ def region(self):
+ return self.location.state.country.lux_region
+
+ @property
+ def longitude(self):
+ '''Get the site's longitude.'''
+ return self.point.x
+
+ @property
+ def latitude(self):
+ '''Get the site's latitude.'''
+ return self.point.y
+
+ def get_small_image(self):
+ for img in self.images.all():
+ for size in img.sizes.all():
+ if size.width > 360 and size.width < 700:
+ return img.get_image_by_size(size)
+
+ def get_absolute_url(self):
+ return reverse("birds:detail", kwargs={"slug": self.bird.slug})
+
+ def __str__(self):
+ return self.ap.common_name
+
+ def save(self):
+ if not self.point:
+ self.point = Sighting.objects.latest().point
+ try:
+ self.location = Location.objects.filter(
+ geometry__contains=self.point
+ ).get()
+ except Location.DoesNotExist:
+ raise forms.ValidationError("There is no location associated with that point, add it: %sadmin/locations/location/add/" % (settings.BASE_URL))
+ super(Sighting, self).save()
+
+"""
+Migration from Birds to abstract:
+birdclass = BirdClass.objects.all()
+for b in birdclass:
+ APClass.objects.create(
+ common_name = b.common_name,
+ scientific_name = b.scientific_name,
+ kind = 1
+ )
+
+birds = Bird.objects.all()
+for b in birds:
+ ap = APClass.objects.get(scientific_name=b.bird_class.scientific_name)
+ print(ap)
+ AP.objects.create(
+ common_name = b.common_name,
+ scientific_name = b.scientific_name,
+ code = b.code,
+ apclass = ap,
+ image = b.image,
+ image_credit = b.image_credit,
+ )
+ print(t)
+
+birdsighting = BirdSighting.objects.all()
+for bird in birdsighting:
+ ap = AP.objects.get(scientific_name=bird.bird.scientific_name)
+ s = Sighting.objects.create(
+ ap = ap,
+ point = bird.point,
+ location = bird.location,
+ date = bird.date,
+ )
+ for t in bird.images.all():
+ s.images.add(t)
+ for t in bird.seen_by.all():
+ s.seen_by.add(t)
+"""
+
class BirdClass(models.Model):
common_name = models.CharField(max_length=200)