ForeignKey上的Annotate F()如何工作?

时间:2017-01-12 18:12:54

标签: django django-models

我有一个非常简单的测试项目,其中包含以下模型:

class Category(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name


class Pizza(models.Model):
    name = models.CharField(max_length=50)
    category = models.ForeignKey(Category, related_name='pizzas')

    def __str__(self):
        return self.name

出于测试目的,我创建了4个“Pizza”实例,所有实例都具有相同的类别:

'Test Pizza'
'Test'
'Another One'
'Yoplahihou'

这是一个简单的代码及其结果:

[print(p.id, p) for p in Pizza.objects.all()]

1 Test Pizza
2 Test
3 Another one
4 Yoplahihou

到目前为止,一切都很好。对此代码进行简单修改以添加注释即可:

[print(p.id, p, "| test:", p.test) for p in Pizza.objects.annotate(test=F('category'))]

1 Test Pizza | test: 1
2 Test | test: 1
3 Another one | test: 1
4 Yoplahihou | test: 1

仍然很好,(它们都属于id为1的类别)。但是我完全失去了它的结果如下:

[print(p.id, p, "| test:", p.test) for p in Pizza.objects.annotate(test=F('category__pizzas'))]

1 Test Pizza | test: 1
1 Test Pizza | test: 2
1 Test Pizza | test: 3
1 Test Pizza | test: 4
2 Test | test: 1
2 Test | test: 2
2 Test | test: 3
2 Test | test: 4
3 Another one | test: 1
3 Another one | test: 2
3 Another one | test: 3
3 Another one | test: 4
4 Yoplahihou | test: 1
4 Yoplahihou | test: 2
4 Yoplahihou | test: 3
4 Yoplahihou | test: 4

有人可以向我解释发生了什么事吗?为什么我在查询中得到了如此多的额外结果?为什么每个“test”的值都不同?

这是一个简单的例子,但我试图在另一个项目的更复杂的查询中重现这一点,我绝对没有结果的这种乘法(但我试图获得它)。如果我能理解这里发生了什么,我可以想出在我的另一个项目中该怎么做。

1 个答案:

答案 0 :(得分:2)

使用此查询:

[print(p.id, p, "| test:", p.test) for p in Pizza.objects.annotate(test=F('category'))]

您选择披萨并加入该类别。

在第二个:

[print(p.id, p, "| test:", p.test) for p in Pizza.objects.annotate(test=F('category__pizzas'))]

您选择披萨并加入该类别(如第一个),然后加入 披萨助手的类别。 类别1与披萨1,2,3,4相关联。

Category 1 | Pizza 1
Category 1 | Pizza 2
Category 1 | Pizza 3
Category 1 | Pizza 4

回到第二个问题,第一行:

1 Test Pizza | Category 1

有4条线相关联。

给你:

1 Test Pizza | test: 1
1 Test Pizza | test: 2
1 Test Pizza | test: 3
1 Test Pizza | test: 4

表披萨中的另一行相同。

Ps:抱歉英语不好