Exemple #1
0
class Born(model.Model):
    """
    Abstract base class that adds a `birth_date`
    field and a virtual field "Age".

    .. attribute:: birth_date

      An :class:`IncompleteDateField <lino.core.fields.IncompleteDateField>`.

    .. attribute:: age

      Virtual field displaying the age in years.

    """
    class Meta:
        abstract = True

    birth_date = fields.IncompleteDateField(blank=True,
                                            verbose_name=_("Birth date"))

    def get_age(self, today=None):
        """Return the age (in years) of this human.
        See :meth:`lino.utils.IncompleteDateField.get_age`.
        """
        if self.birth_date:
            return self.birth_date.get_age(today or settings.SITE.today())

    def get_exact_age(self, today=None):
        """
        Return the age as a :class:`datetime.timedelta` object.

        `ar` is the requesting :class:`ActionRequest` which can be `None`
        because it is ignored.

        Optional keyword argument `today` should be a
        :class:`datetime.date` instance to replace the actual current
        date. This is used if you want the age at a given date in the past
        or the future.
        The default value calls :meth:`dd.Site.today`.
        """
        if self.birth_date and self.birth_date.year:
            if today is None:
                today = settings.SITE.today()
            try:
                return today - self.birth_date.as_date()
            except ValueError:
                pass

    @fields.displayfield(_("Age"))
    def age(self, request, today=None):
        a = self.get_exact_age(today)
        if a is None:
            return unicode(_('unknown'))
        s = _("%d years") % (a.days / 365)
        if self.birth_date and self.birth_date.is_complete():
            return s
        return u"±" + s
Exemple #2
0
class Born(model.Model):
    """
    Abstract base class that adds a `birth_date` field and a virtual
    field "Age".

    .. attribute:: birth_date

      An :class:`IncompleteDateField <lino.core.fields.IncompleteDateField>`.

    .. attribute:: age

      Virtual field displaying the age in years.
    """
    class Meta(object):
        abstract = True

    birth_date = fields.IncompleteDateField(blank=True,
                                            verbose_name=_("Birth date"))

    def get_age(self, today=None):
        """
        Return the age (in years) of this human.  See
        :meth:`lino.utils.IncompleteDateField.get_age`.
        """
        if self.birth_date:
            return self.birth_date.get_age(today or settings.SITE.today())

    def get_exact_age(self, today=None):
        """
        Return the age as a :class:`datetime.timedelta` object.

        Optional keyword argument `today` should be a
        :class:`datetime.date` instance to replace the actual current
        date. This is used if you want the age at a given date in the past
        or the future.
        The default value calls :meth:`dd.Site.today`.
        """
        # print(20160202, self.birth_date, self)
        if self.birth_date and self.birth_date.year:
            if today is None:
                today = settings.SITE.today()
            try:
                return today - self.birth_date.as_date()
            except ValueError:
                pass

    @fields.displayfield(_("Age"))
    def age(self, ar, today=None):
        a = self.get_exact_age(today)
        if a is None:
            return str(_('unknown'))
        years = old_div(a.days, 365)
        if years == 1:
            s = _("{} year").format(years)
        else:
            s = _("{} years").format(years)
        if years <= 4:
            months = old_div(a.days - years * 365, 30)
            if months == 1:
                s += " " + _("{} month").format(months)
            else:
                s += " " + _("{} months").format(months)
        if self.birth_date and self.birth_date.is_complete():
            return s
        return u"±" + s

    @classmethod
    def setup_parameters(cls, fields):
        fields.update(aged_from=models.IntegerField(
            _("Aged from"),
            blank=True,
            null=True,
            help_text=_("Select only persons aged at least "
                        "the given number of years.")),
                      aged_to=models.IntegerField(
                          _("Aged to"),
                          blank=True,
                          null=True,
                          help_text=_("Select only persons aged at most "
                                      "the given number of years.")))
        super(Born, cls).setup_parameters(fields)

    @classmethod
    def get_request_queryset(cls, ar, **filter):
        qs = super(Born, cls).get_request_queryset(ar, **filter)
        pv = ar.param_values

        today = settings.SITE.today()

        if pv.aged_from:
            min_date = today - \
                datetime.timedelta(days=pv.aged_from * 365)
            qs = qs.filter(birth_date__lte=min_date.strftime("%Y-%m-%d"))

        if pv.aged_to:
            max_date = today - \
                datetime.timedelta(days=pv.aged_to * 365)
            qs = qs.filter(birth_date__gte=max_date.strftime("%Y-%m-%d"))

        return qs

    @classmethod
    def get_title_tags(self, ar):
        for t in super(Born, self).get_title_tags(ar):
            yield t
        pv = ar.param_values
        if pv.aged_from or pv.aged_to:
            yield str(
                _("Aged %(min)s to %(max)s") %
                dict(min=pv.aged_from or '...', max=pv.aged_to or '...'))