如何编写一对多关系中的反向关系的Django ORM查询?

时间:2019-01-21 15:26:18

标签: python sql django python-3.x orm

我正在使用Django和Python 3.7。我的models.py文件中有以下两个模型...

class Article(models.Model):
    created_on = models.DateTimeField(default=datetime.now)
...


class ArticleStat(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE, )
    elapsed_time_in_seconds = models.IntegerField(default=0, null=False)

我想编写一个Django ORM查询,在该查询中,我选择的文章的统计信息至少存在5分钟(300秒)。但是,我不知道如何从Article对象中引用ArticleStat对象。毫不奇怪,这

Article.objects.filter(articlestat.elapsed_time_in_seconds.lte==300)

产生

NameError: name 'articlestat' is not defined

错误。

编辑:按照答案,我将ArticleStat模型更改为

class ArticleStat(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='articlestats')

然后运行以下查询以显示错误

Article.objects.filter(articlestat_set__elapsed_time_in_seconds__lte==300)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'articlestat_set__elapsed_time_in_seconds__lte' is not defined

认为可能存在一个具有多个实例,所以我尝试了“ s”,但出现了错误..

Article.objects.filter(articlestats_set__elapsed_time_in_seconds__lte==300)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'articlestats_set__elapsed_time_in_seconds__lte' is not defined

2 个答案:

答案 0 :(得分:2)

这里的核心问题是NameError的{​​{1}},所以我将首先解决。

django documentation中所述,默认情况下,您的向后关系名称定义为 articlestat ,在您的情况下,其含义为FOO_set

  

如果模型具有ForeignKey,则为外键模型的实例   将有权访问一个Manager,该返回值是   第一个模型。默认情况下,此Manager名为 FOO_set ,   其中 FOO 是源模型名称,小写。

如果您希望使用其他名称,可以通过在articlestat_set定义中指定related_name来实现,例如

ForeignKey

第二个问题是如何正确遵循here进行了广泛解释的关系,这就是为什么我在此答案中不做详细介绍。要点是您想使用class ArticleStat(models.Model): article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='articlestats') elapsed_time_in_seconds = models.IntegerField(default=0, null=False) (双下划线)代替.运算符。 field lookups也是如此,您需要在此查询中进行比较。

同时解决了这两个问题,您的查询应如下所示:

__

或使用自定义Article.objects.filter(articlestat_set__elapsed_time_in_seconds__lte=300) ,例如related_name

related_name='articlestats'

答案 1 :(得分:1)

尝试类似的东西:

Article.objects.filter(articlestat__elapsed_time_in_seconds__lte=300)

请注意,Django查询的工作方式与关键字(kwargs)相同(即,您只能将filter_string=something传递给过滤器函数)。

您正在传递python无法解析的表达式(即python试图找到articlestat变量名,然后获取其elapsed_time_in_seconds属性,等等)

进一步了解https://docs.djangoproject.com/en/2.1/topics/db/queries/#retrieving-specific-objects-with-filters