0

I have a Django class to convert the date of birth (dob) field in my model to age and annotate the result to a queryset.

class CalculateAge(Case):
    def __init__(self, model, field, condition=None, then=None, **lookups):
        today = date.today()
        obj = model.objects.first()
        field_object = model._meta.get_field(field)
        field_value = field_object.value_from_object(obj)
        bornyear = field_value.year
        bornmonth = field_value.month
        bornday = field_value.day
        # something is wrong with the next two lines
        age = [today.year - bornyear - ((today.month, today.day) < (bornmonth, bornday))]
        return super().__init__(*age, output_field=IntegerField())

however when I try to pass the result to my queryset

queryset = Person.objects.all().annotate(age=CalculateAge(Person, 'dob')

I get the error

Positional arguments must all be When objects.

How can I get this to work?

24thDan
  • 113
  • 1
  • 9
  • I don't understand what you're doing. CalculateAge is a class that extends Case but you use it like a function that returns a number. Are you sure you want CalculateAge to be a class and are you sure you want it to extend Case? – lucutzu33 May 30 '21 at 00:04
  • Case is not mandatory. Open to any implementation that can be used to populate the annotated value “age” – 24thDan May 30 '21 at 01:07

1 Answers1

1

There is an easier way. Just add a function on your model to get the age like this:

class ModelName(models.Model):
    birth_date = models.DateField()
    #other fields

    def get_age(self):
        age = datetime.date.today()-self.birth_date
        return int((age).days/365.25)
MeL
  • 1,269
  • 3
  • 12
  • 30