models.py 3.84 KB
Newer Older
Evili del Rio's avatar
Evili del Rio committed
1 2
from django.conf import global_settings
from django.conf import settings
3
from django.db import models
Evili del Rio's avatar
Evili del Rio committed
4 5
from django.utils.translation import get_language

Evili del Rio's avatar
Evili del Rio committed
6 7 8
class BaseNameManager(models.Manager):
    def get_by_natural_key(self, name):
        return self.get(name=name)
9

10
class BaseName(models.Model):
Evili del Rio's avatar
Evili del Rio committed
11 12
    objects = BaseNameManager()

13
    name = models.CharField(max_length=255, unique=True)
14
    notes = models.TextField(null=True, blank=True)
15

16 17 18
    def __str__(self):
        return self.name

Evili del Rio's avatar
Evili del Rio committed
19 20 21
    def natural_key(self):
        return (self.name,)

22 23 24 25 26 27 28 29
    class Meta:
        abstract = True
        ordering = ['name']


class Kingdom(BaseName):
    pass

Evili del Rio's avatar
Evili del Rio committed
30

31
class Phylum(BaseName):
Evili del Rio's avatar
Evili del Rio committed
32
    kingdom = models.ForeignKey(Kingdom, on_delete=models.PROTECT)
Evili del Rio i Silvan's avatar
Evili del Rio i Silvan committed
33

Evili del Rio's avatar
Evili del Rio committed
34

35
class Classe(BaseName):
Evili del Rio's avatar
Evili del Rio committed
36
    phylum = models.ForeignKey(Phylum, on_delete=models.PROTECT)
37

Evili del Rio's avatar
Evili del Rio committed
38

Evili del Rio's avatar
Evili del Rio committed
39
class Ordo(BaseName):
Evili del Rio's avatar
Evili del Rio committed
40
    classe = models.ForeignKey(Classe, on_delete=models.PROTECT)
Evili del Rio's avatar
Evili del Rio committed
41

Evili del Rio's avatar
Evili del Rio committed
42

Evili del Rio's avatar
Evili del Rio committed
43
class Family(BaseName):
Evili del Rio's avatar
Evili del Rio committed
44
    ordo = models.ForeignKey(Ordo, on_delete=models.PROTECT)
Evili del Rio's avatar
Evili del Rio committed
45

Evili del Rio's avatar
Evili del Rio committed
46

Evili del Rio's avatar
Evili del Rio committed
47
class Genus(BaseName):
Evili del Rio's avatar
Evili del Rio committed
48
    family = models.ForeignKey(Family, on_delete=models.PROTECT)
Evili del Rio's avatar
Evili del Rio committed
49

50

Evili del Rio's avatar
Evili del Rio committed
51 52 53
class LocaleManager(models.Manager):
    """Model Manger for available Locales"""

Evili del Rio's avatar
Evili del Rio committed
54 55 56
    def get_by_natural_key(self, locale):
        return self.get(locale=locale)

Evili del Rio's avatar
Evili del Rio committed
57 58 59
    @staticmethod
    def enabled_locales():
        """Work with enabled languages only."""
Evili del Rio's avatar
Evili del Rio committed
60
        return list(zip(*settings.LANGUAGES))[0]
Evili del Rio's avatar
Evili del Rio committed
61 62

    def get_queryset(self):
Evili del Rio's avatar
Evili del Rio committed
63
        return super().get_queryset().filter(
Evili del Rio's avatar
Evili del Rio committed
64 65 66 67 68 69 70 71 72
                locale__in=self.enabled_locales())


class Locale(models.Model):
    """Locale are the language code for the Species Common Names"""
    locale = models.CharField(max_length=15, 
                              choices=global_settings.LANGUAGES,
                              unique=True)
    objects = LocaleManager()
Evili del Rio's avatar
Evili del Rio committed
73 74 75 76
    
    def natural_key(self):
        return (self.locale,)

Evili del Rio's avatar
Evili del Rio committed
77 78 79 80 81 82

class Species(BaseName):
    """Species s one of the basic units of biological classification and a
    taxonomic rank. A species is often defined as a group of organisms capable
    of interbreeding and producing fertile offspring.
    """
Evili del Rio's avatar
Evili del Rio committed
83
    genus = models.ForeignKey(Genus, on_delete=models.PROTECT)
Evili del Rio's avatar
Evili del Rio committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102

    def sci_name(self):

        """Scientific name of the especies. It's formed by the capitalized
        Genus name followed by the proper name.
        """

        return self.genus.name.capitalize()+u' '+self.name.lower()

    def __str__(self):
        """Return the Common Name of the Species in the current Locale. If
        there is not a Common Name, return the Scientific Name.
        """
        cn = self.sci_name()

        try:
            loc = get_language()
        except:
            loc = settings.LANGUAGE_CODE
Evili del Rio's avatar
Evili del Rio committed
103

Evili del Rio's avatar
Evili del Rio committed
104 105 106
        try:
            lang = Locale.objects.get(locale=loc)
        except:
Evili del Rio's avatar
Evili del Rio committed
107 108 109 110
            try:
                loc = loc.replace('-', '_').split('_')[0]
            except:
                pass
Evili del Rio's avatar
Evili del Rio committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

        try:
            lang = Locale.objects.get(locale=loc)
        except:
            lang, created = Locale.objects.get_or_create(locale='en')
        try:
            cn = self.commonname_set.get(locale=lang).cname
        except:
            pass

        return cn

    def __unicode__(self):
            return self.__str__()

    class Meta:
        ordering = ['genus', 'name']
        verbose_name_plural = 'species'


class CommonName(models.Model):
    """A Common Name for any Species in some language. For simplicity,
    there should be only one Common Name for a given Species in a
    given Language.
    """

    cname = models.CharField(max_length=127)
Evili del Rio's avatar
Evili del Rio committed
138 139
    species = models.ForeignKey(Species, on_delete=models.PROTECT)
    locale = models.ForeignKey(Locale, on_delete=models.PROTECT)
Evili del Rio's avatar
Evili del Rio committed
140 141 142 143 144 145 146

    def __unicode__(self):
        return u'{0} ({1})'.format(self.cname, self.species.sci_name())

    class Meta:
        ordering = ['locale', 'species']
        unique_together = ['locale', 'species']