django - 有没有办法查询来自生日的人口统计数据?
问题描述
我正在尝试生成人口统计数据。我做了所有单独的查询,因为我想不出一次做这些的方法。
from django.utils import timezone
from dateutil.relativedelta import relativedelta # $ pip install python-dateutil
teenagers_count = queryset.filter(birthday__lte=now-relativedelta(years=10), birthday__gt=now-relativedelta(years=20)).count()
twenties_count = queryset.filter(birthday__lte=now-relativedelta(years=20), birthday__gt=now-relativedelta(years=30)).count()
thirties_count = queryset.filter(birthday__lte=now-relativedelta(years=30), birthday__gt=now-relativedelta(years=40)).count()
forties_count = queryset.filter(birthday__lte=now-relativedelta(years=40), birthday__gt=now-relativedelta(years=50)).count()
fifties_and_older_count = queryset.filter(birthday__lte=now-relativedelta(years=50)).count()
有没有办法通过一个查询来做到这一点?
解决方案
首先,将您的年龄注释到您的查询集,使用:
age = ExpressionWrapper(datetime.now() - F('created_at'), output_field=fields.DurationField())
queryset.annotate(age=age) #=> Will add "age" on each records
二、使用Case/When来组成自己的age_range
字段逻辑
queryset.annotate(age=age).annotate(
age_range=Case(
When(age__gte=datetime.timedelta(years=10), age__lt=datetime.timedelta(years=20), then=Value('teens')),
When(age__gte=datetime.timedelta(years=20), age__lt=datetime.timedelta(years=30), then=Value('twenties')),
When(age__gte=datetime.timedelta(years=30), age__lt=datetime.timedelta(years=40), then=Value('thirties')),
When(age__gte=datetime.timedelta(years=40), age__lt=datetime.timedelta(years=50), then=Value('fourties')),
When(age__gte=datetime.timedelta(years=50), then=Value('fifties')),
default=Value('Unknow'),
output_field=fields.CharField(),
)) #=> This will add "age_range" field on your queryset
第三,只需按“age_range”聚合。全部一起:
import datetime
from django.db.models import Case, When, Value, F, Count, ExpressionWrapper, fields
age = ExpressionWrapper(datetime.now() - F('created_at'), output_field=fields.DurationField())
counts = queryset.annotate(age=age).annotate(
age_range=Case(
When(age__gte=datetime.timedelta(years=10), age__lt=datetime.timedelta(years=20), then=Value('teens')),
When(age__gte=datetime.timedelta(years=20), age__lt=datetime.timedelta(years=30), then=Value('twenties')),
When(age__gte=datetime.timedelta(years=30), age__lt=datetime.timedelta(years=40), then=Value('thirties')),
When(age__gte=datetime.timedelta(years=40), age__lt=datetime.timedelta(years=50), then=Value('fourties')),
When(age__gte=datetime.timedelta(years=50), then=Value('fifties')),
default=Value('Unknow'),
output_field=fields.CharField(),
)).order_by('age_range').values('age_range').annotate(count=Count('age_range'))
推荐阅读
- angular - Angular 6如何等待httpclient返回
- java - MongoDB:如何确保从分片集群中读取特定辅助节点?
- javascript - 如何使用自定义功能扩展引导模式
- sockets - jxbrowser 套接字服务器挂起
- c# - c#解码从python套接字发送的字节[]
- python - 如何比较两个字典值列表,并在 Python3 中另一个列表值发生变化时更新列表值?
- web-services - 如何获取完整的跟踪信息(Fedex Webservices)?
- reactjs - 是否可以将 React 应用程序渲染为静态 HTML 文件,就好像它是服务器渲染的一样
- python - 我可以使用解释器更新 Conda 环境吗
- css - 图片:我需要 100% 的高度比 100% 的宽度更重要