import datetime from django.core.urlresolvers import reverse from django.template.defaultfilters import slugify from django.contrib.gis.db import models from django.contrib.auth.models import User from django.utils import timezone from locations.models import Location from django import forms from django.conf import settings from photos.models import LuxImage def get_upload_path(self, filename): return "images/bird-images/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename) # from http://aba.org/checklist/codes.html ABA_CODES = ( (1, 'regular occurring - common'), (2, 'regular occurring - less common'), (3, 'rare'), (4, 'casual'), (5, 'accidental'), (6, 'Cannot be found'), ) class BirdClass(models.Model): common_name = models.CharField(max_length=200) scientific_name = models.CharField(max_length=200) class Meta: verbose_name_plural = 'Bird Class' ordering = ["common_name", ] def __str__(self): return self.common_name class Bird(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) bird_class = models.ForeignKey(BirdClass) 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 # function to resize large image to 680px wide and use as normal image # the question is, should this happen here, or with some universale image # model that can be attached to other models, loaded in entries and # displayed in galleries. I suppose the answer is yes then isn't it? # the problem is that I still can't see exactly what that looks like... 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("birds:detail", kwargs={"slug": self.slug}) class Meta: ordering = ["common_name", ] def save(self): self.slug = slugify(self.common_name[:50]) super(Bird, self).save() class BirdAudio(models.Model): bird = models.ForeignKey(Bird, related_name='recordings') audio = models.FileField(upload_to='audio/birds/') recorder = models.CharField(max_length=200, null=True, blank=True) pub_date = models.DateTimeField() location = models.CharField(max_length=200, null=True, blank=True) link = models.CharField(max_length=450, null=True, blank=True) copyright = models.CharField(max_length=250, null=True, blank=True) class Meta: verbose_name_plural = 'Bird Audio' ordering = ["bird", ] def __str__(self): return self.bird.common_name class BirdSighting(models.Model): bird = models.ForeignKey(Bird) point = models.PointField() location = models.ForeignKey(Location, blank=True) date = models.DateTimeField('Date', default=timezone.now) seen_by = models.ManyToManyField(User) images = models.ManyToManyField(LuxImage) audio = models.ManyToManyField(BirdAudio) class Meta: verbose_name_plural = 'Bird Sighting' @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.bird.common_name def save(self): 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(BirdSighting, self).save()