我在这里与某些东西打架我正在使用django,你可以帮助我。
我有一个带有date_of_birth字段的帐户模型,我有一个查找年龄的方法。
class Account(AbstractBaseUser, PermissionsMixin):
date_of_birth = models.DateField()
def age(self):
"""
Returns the age from the date of birth
"""
today = datetime.date.today()
try:
birthday = self.date_of_birth.replace(year=today.year)
except ValueError: # raised when birth date is February 29 and the current year is not a leap year
birthday = self.date_of_birth.replace(year=today.year, day=self.date_of_birth.day-1)
if birthday > today:
return today.year - self.date_of_birth.year - 1
else:
return today.year - self.date_of_birth.year
我想知道是否有可能从这样的查询中获得年龄:
list = Account.objects.filter('account__age__gte', today)
我已经尝试但是我收到了这个错误:
无法将关键字'age'解析为字段。选择是:......
只显示我的字段。不是方法。\
感谢您的帮助。
非常感谢。
答案 0 :(得分:2)
您无法直接查询模型方法,因为自定义方法无法评估其对应的SQL查询。
您有几个选择:
在视图中,计算出给定年龄的最早出生日期。例24年:
from dateutil.relativedelta import relativedelta
datetime.date.today() - relativedelta(years=24)
datetime.date(1989, 11, 15)
现在,查询将位于date_of_birth
字段。
请注意,dateutil
是第三方库,默认情况下可能不适用于您的python。 (如果你想使用timedelta,你也可以这样做,因为datetime.timedelta
是python内置的)
另一个选项(效率稍差)是获取对象查询集,并使用列表推导来过滤掉不需要的记录。
qs = Account.objects.all()
qs = [account for account in qs if account.age() > 24]
24,显然只是一个例子。用一些“理智”的价值取而代之。
答案 1 :(得分:0)
我知道你已经有了这个答案并且答案是准确的,但我认为你可以将你的年龄方法变成一个属性(实际上,我认为这就是模型属性的用途,但我会如果我错的话,很乐意在这一点上予以纠正)。
因此,您可以这样做:
class Account(AbstractBaseUser, PermissionsMixin):
date_of_birth = models.DateField()
def _age(self):
"""
Returns the age from the date of birth
"""
today = datetime.date.today()
... {value is computed and returned} ...
age = property(_age)
这当然不能解决您的过滤问题;它只是让它更容易处理方法,就像它是一个实例属性,你的SQL查询仍然需要抓取所有内容,或者按date_of_birth
过滤(如果你要做很多事情,可能会很好包括作为自定义经理)。