如何使用Django ORM计算从出生年份到注册日期的用户年龄

时间:2016-01-16 14:39:22

标签: python mysql django django-models

我有一个包含字段birth_year的模型,而在另一个模型中我有用户注册日期。 我有用户ID列表,如果他们的年龄属于特定的年龄范围,我想查询。用户年龄计算为注册日期 - birth_year。

我能够从当前日期计算出来:

startAge=25
endAge=50
ageStartRange = (today - relativedelta(years=startAge)).year
ageEndRange = (today - relativedelta(years=endAge)).year

我将查询作为:

query.filter(profile_id__in=communityUsersIds, birth_year__lte=age_from, birth_year__gte=age_to).values('profile_id')

这样我就可以获得年龄在bw 25和50范围内的用户ID。而不是今天我如何使用registration_date(它是另一个模型中的一个字段)。

2 个答案:

答案 0 :(得分:1)

查询的“今天”版本很容易,因为“今天”日期不依赖于行中的各个字段。

F表达式

您可以探索Django的F表达式,因为它们允许您在查询中引用模型的字段(不将它们拉入Python)

https://docs.djangoproject.com/en/1.7/topics/db/queries/#using-f-expressions-in-filters

e.g。对你来说, age 就是这个F表达式:

F('registration_date__year') - F('birth_year')

但是,我们确实不需要计算,因为例如要查询您想要的内容,请考虑以下问题:

Model.filter(birth_year__lte=F('regisration_date__year') - 25)

从那里你可以添加一个:

birth_year__gte=F('regisration_date__year') + 50

或使用birth_year__range=(F('regisration_date__year') - 25, F('regisration_date__year') + 50))

替代方案:预先计算年龄

否则,您可以预先计算年龄,因为该值在用户注册时间是可知的

Model.update(age=F('registration_date__year') - F('birth_year'))

保存后,它就像Model.filter(age__range=(25, 50))

一样简单

答案 1 :(得分:0)

您可以使用本机数据库函数。使用 Postgres 就像一个魅力。

from django.contrib.auth.models import User
from django.db.models import DurationField, IntegerField, F, Func


class Age(Func):
    function = 'AGE'
    output_field = DurationField()


class AgeYears(Func):
    template = 'EXTRACT (YEAR FROM %(function)s(%(expressions)s))'
    function = 'AGE'
    output_field = IntegerField()


users = User.objects.annotate(age=Age(F("dob")), age_years=AgeYears(F("dob"))).filter(age_years__gte=18)
for user in users:
    print(user.age, user.age_years)

# which will generate result like below
# 10611 days, 0:00:00 29

相关问题