我有一个包含字段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(它是另一个模型中的一个字段)。
答案 0 :(得分:1)
查询的“今天”版本很容易,因为“今天”日期不依赖于行中的各个字段。
您可以探索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