我的 Django 模型(作者)中有一个出生日期 ( dob ) DateField 。我尝试注释年龄参数。我搜索了许多可能的方法来做到这一点,每个过程都会产生某种错误。
在这里,我首先在 python 控制台中尝试确保表达式是有效的:
>>> from datetime import datetime
>>> (datetime.now() - datetime(2000,1,1)).days #output: 7506
Run Code Online (Sandbox Code Playgroud)
第一次尝试:
>>> from django.db.models import F
>>> authors = Author.objects.annotate(age = (datetime.now()-F('dob')).days) #no-error here
>>> print(authors) # Exception thrown here
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/puru/Documents/Python/django/prac1/django-master/lib/python3.7/site-packages/Django-3.2-py3.7.egg/django/db/models/query.py", line 324, in __getitem__
qs._fetch_all()
File "/home/puru/Documents/Python/django/prac1/django-master/lib/python3.7/site-packages/Django-3.2-py3.7.egg/django/db/models/query.py", line 1305, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/home/puru/Documents/Python/django/prac1/django-master/lib/python3.7/site-packages/Django-3.2-py3.7.egg/django/db/models/query.py", line 70, in __iter__
for row in compiler.results_iter(results):
File "/home/puru/Documents/Python/django/prac1/django-master/lib/python3.7/site-packages/Django-3.2-py3.7.egg/django/db/models/sql/compiler.py", line 1100, in apply_converters
value = converter(value, expression, connection)
File "/home/puru/Documents/Python/django/prac1/django-master/lib/python3.7/site-packages/Django-3.2-py3.7.egg/django/db/backends/sqlite3/operations.py", line 291, in convert_datefield_value
value = parse_date(value)
File "/home/puru/Documents/Python/django/prac1/django-master/lib/python3.7/site-packages/Django-3.2-py3.7.egg/django/utils/dateparse.py", line 75, in parse_date
match = date_re.match(value)
TypeError: expected string or bytes-like object
Run Code Online (Sandbox Code Playgroud)
我第二次使用 ExpressionWrapper 定义输出类型为 DateTimeField
>>> from django.db.models import DateTimeField, ExpressionWrapper
>>> authors = Author.objects.annotate(age = ExpressionWrapper(timezone.now() - F('dob'), output_field=DateTimeField()).days)
AttributeError: 'ExpressionWrapper' object has no attribute 'days'
Run Code Online (Sandbox Code Playgroud)
我也尝试过RawSQL。我这里使用的是Sqlite数据库。所以date('now')将为我提供当前日期。
>>> from django.db.models.expressions import RawSQL
>>> authors = Author.objects.annotate(age=RawSQL("date('now')-dob"))
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'params'
Run Code Online (Sandbox Code Playgroud)
那么有什么办法可以解决我的问题吗?
你已经快到了,问题是output_field价值。它应该DurationField代替DateTimeField
age_expr = ExpressionWrapper(timezone.now() - F('dob'), output_field=DateTimeField())
queryset = Author.objects.annotate(age=age_expr)Run Code Online (Sandbox Code Playgroud)
注意:您不能使用.dayswith ExpressionWrapper,因为注释操作是在数据库级别执行的。
要计算年龄,您可能需要使用以下.total_seconds()方法
print(queryset[0].age.total_seconds() / 60 / 60 / 24 / 365.25)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2076 次 |
| 最近记录: |