django - Django - 使用查询集左加入日期数组
问题描述
在我的 Django 项目中,我有以下模型:
class Examine(models.Model):
name = models.CharField(max_length=45)
date = models.DateField(blank=True, null=True)
我的目标是提出一个查询集,使我能够呈现带有日期列表和日期检查的模板 - 如果有的话。例如,我在数据库中有三个检查:
Math - 01 January 2019,
History - 03 January 2019
Geoghraphy - 03 January 2019
我对 2019 年 1 月 1 日至 1 月 4 日的日期间隔感兴趣。输出应该是:
January 1
Math
January 2
No exams
January 3
History
Geography
January 4
No exams
我有两年使用 Django ORM 的经验,但我什至无法提交我如何尝试实现它的任何尝试。我没有想法。在 Django 中可能吗?
解决方案
从您知道的可能开始 - 使用此处文档中描述的日期范围过滤器从数据库中获取考试。
from datetime import date
start_date = date(2019, 1, 1)
end_date = date(2019, 1, 4)
exams = Examine.objects.filter(date__gte=start_date, date__lte=end_date).order_by('date')
我想你可能会陷入对日期进行“左连接”的想法。这在原始 SQL 查询中是可能的,但在这里不是必需的。
本质上,我们要做的是在从相关日期范围获取考试后,仅在 Python 代码中执行左连接操作。
让我们创建一个可以支持我们想要做的事情的数据结构:
from collections import defaultdict
exams_by_day = defaultdict(list)
for exam in exams:
exams_by_day[exam.date].append(exam)
因为它是一个defaultdict
,如果我们访问一个不存在的键,我们将得到一个空列表。
最后一部分是为左列生成日期列表:
from datetime import timedelta
date_diff = end - start # a timedelta object (3 days)
dates = []
for i in range(date_diff.days + 1):
dates.append(start + timedelta(days=i))
最后,我们可以将这两个数据结构都传递到我们的模板中并对其进行迭代以生成您想要的输出:
<dl>
{% for date_ in dates %}
<dt>{{ date_|date:"F j"}}</dt>
<dd>
<ol>
{% with exams=exams_by_date.date %}
{% for exam in exams %}
<li>{{ exam.name }}</li>
{% empty %}
<li>No exams</li>
{% endfor %}
</ol>
</dd>
{% endfor %}
</dl>
请参阅https://docs.djangoproject.com/en/2.0/ref/templates/builtins/
以了解with
及|date:"F j"
以上的详细信息。
推荐阅读
- excel - 服务器执行创建 Outlook 应用程序失败
- ios - 动作 ML 分类器未给出预期结果
- python - 更改 Gurobi 中的下限
- html - 当我单击播放按钮时,它显示一条错误消息“无法读取 null 的属性 'play'”
- firebase - 如何计算 Firebase 事件中的“每位用户计数”值
- linux - 需要调试 MMAP 那么 MMAP 的目标文件或包含 MMAP() 的模块在哪里——如何在 linux 中找到?
- python - python csv,删除所有逗号,但每行的第一个和最后一个
- c# - 在 xamarin 中滚动 CollectionView 图片时,它的滞后,该怎么办?
- java - Java中不同方式调用变量的影响
- flutter - 颤振:RangeError(索引):无效值:不在包含范围内0..52:53即使有项目计数也会出错