python - 如何在我的 Django ORM 查询中将 timedelta 与列一起使用?
问题描述
我正在使用 Django 和 Python 3.7。我有以下两种型号...
class Article(models.Model):
...
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, related_name="articles",)
created_on = models.DateTimeField(default=datetime.now)
class WebPageStat(models.Model):
...
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, related_name="stats", )
elapsed_time_in_seconds = models.FloatField(default=0)
score = models.BigIntegerField(default=0)
class Publisher(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
我想编写一个 Django ORM 查询,在给定发布者和以秒为单位的经过时间(WebPageStat 记录)的情况下,我找到所有“created_on”日期不早于以秒为单位的经过时间的文章。许多人建议在其他帖子中使用“timedelta”,但这似乎对我不起作用......
Article.objects.filter(created_on__lte=datetime.now(timezone.utc) - timedelta(hours=0, minutes=0, seconds=publisher__stats__elapsed_time_in_seconds))
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'publisher__stats__elapsed_time_in_seconds' is not defined
我可以将 timedelta 与 SQL 列逻辑一起使用吗?否则我该怎么做?
解决方案
这里的根本问题是你不明白为什么你会收到错误
name 'publisher__stats__elapsed_time_in_seconds' is not defined`.
我们再看一下代码:
Article.objects.filter(created_on__lte=datetime.now(timezone.utc) -
timedelta(hours=0, minutes=0, seconds=publisher__stats__elapsed_time_in_seconds))
在上面的代码中,符号publisher__stats__elapsed_time_in_seconds
被解释为变量引用,这在您的代码中没有定义。如果您添加了
publisher__stats__elapsed_time_in_seconds = 1
就在上面的代码片段之前,那么您将不会收到错误消息。(你也不会得到你想要的结果。)你期望 Django 的 ORM 对符号进行操作,publisher__stats__elapsed_time_in_seconds
但在 Django 可以得到它之前,Python 解释器必须解释代码,以及代码的编写方式,这只是一个解释器必须解析的变量名。Django 甚至没有机会看到它。
好的,防止解释器将名称解释为变量引用并让 Django ORM 处理名称的方法是使用F()
表达式。所以你很想这样做:
Article.objects.filter(created_on__lte=datetime.now(timezone.utc) -
timedelta(hours=0, minutes=0, seconds=F("publisher__stats__elapsed_time_in_seconds")))
但是随后您将传递给timedelta
它不知道如何处理的参数。
正如 Schillingt 在评论中指出的那样,Lutz Prechelt在其他地方的回答显示了如何将F()
表达式移到timedelta
. 在你的情况下,你可以这样做:
Article.objects.filter(created_on__lte=datetime.now(timezone.utc) -
timedelta(seconds=1) * F("publisher__stats__elapsed_time_in_seconds"))))
推荐阅读
- allure - 如何动态生成魅力报告
- java - 在 Eclipse 中创建自定义 JUnit 启动配置
- php - Symfony 单元测试
- php - 移动目录时 Facebook SDKv5 登录失败
- python - 从 magibricks.com 抓取数据
- android-studio - Android构建错误:无法加载'javax.xml.bind.jaxbeexception
- xml - XML到c#字符串数组
- sql - 乘以 2 直到特定数字变为并回答
- hive - 我在 csv 文件中的日期格式为 1989-09-26T09:00:00.000+05:30
- c# - System.TypeLoadException:无法使用令牌 01000115 解析类型