It's true, you can not do a filter on methods, since many of the things that we create are not understood by the API that connects to the database, so you have to work with what the API offers.
Investigating your question a little, I think I can solve it with the use of annotations, like this:
from django.db import models
queryset = Beneficiario.objects.annotate(edad=
models.ExpressionWrapper(
datetime.now().date() - models.F('fechaNacimiento') + datetime.timedelta(days=1)
, output_field=models.DurationField())
)
In this way you already have in queryset
the ages of each beneficiary, you can check it by doing the following:
>>> queryset[0].edad
datetime.timedelta(632, 28172) # son datos inventados
What you see here, is the delta of the time elapsed from birth to today. It only remains to filter.
As you said in your question, you want to do it by ranges, and as you have defined ranges, it's just doing this.
Since you are working with a time delta, you do not need to have exact dates, if not something a little more relative, that is, know that from Monday to Monday there are 8 days, therefore, continuing with that idea it is valid to say that:
RANGE_0_TO_20 = (
datetime.date.today() - datetime.date.today(),
datetime.date(year=2017, month=1, day=2) - datetime.date(year=1997, month=1, day=1)
)
Here I put that example date, but you can put any date, the important thing is that there are 7,300 days of difference for the 20 years, so you will not have anything harked (in the other answer of @jorge when people of 20 years will be 40 years old, will continue to come out in the consultation of people who are 20 years old, so it is harked, here it will be dynamic).
I add the 40 year old, and you can add as many as you want:
RANGE_20_TO_40 = (
datetime.date(year=2017, month=1, day=2) - datetime.date(year=1997, month=1, day=1),
datetime.date(year=2017, month=1, day=2) - datetime.date(year=1987, month=1, day=1)
)
Having the ranges already established, I would do a manager
with a queryset
to avoid repeating myself, but for reasons, that is not the question, you would do the filter as follows:
queryset.filter(edad__range=RANGE_0_TO_20)
queryset.filter(edad__range=RANGE_20_TO_40)
With this, I hope I have helped you, any questions, ask: D