Django ORM的`.first`能否为非空查询集返回`None`?

2024-10-05 12:20:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个非常简单的模型Achievement。在一个算法中,我到达了一个点,在这个点上我有一个这个模型的查询集,名为achievementsbellow。我遇到了这样一种情况:应用于这个查询集的方法.first()输出None,即使查询集中有一个元素

总之

achievements[0] # outputs an achievement
achievements.first() # None
achievements.count() # 1

这怎么会发生?此型号没有默认订购


Tags: 方法模型算法nonean元素count情况
1条回答
网友
1楼 · 发布于 2024-10-05 12:20:58

在查询集上调用.first()时,查询集的顺序很重要,因为这将决定首先是哪个对象。当queryset有一个顺序时,它将被使用,如果它没有,主键将自动用于排序。引用first()上的documentation

Returns the first object matched by the queryset, or None if there is no matching object. If the QuerySet has no ordering defined, then the queryset is automatically ordered by the primary key. This can affect aggregation results as described in Interaction with default ordering or order_by().

在顺序中自动使用主键,或者说,您提供的其他一些顺序将改变聚合的发生方式(正如前面所述,由于顺序的原因,组中可能存在的内容现在将不在组中)。因此,您可以观察查询的结果

考虑下面的示例(^ {< CD3>}模型是不需要的,但这是我已经为测试目的所做的):

class Bar(models.Model):
    value = models.IntegerField()


class ForeignFoo(models.Model):
    bar = models.ForeignKey(Bar, on_delete=models.CASCADE)
    int_field = models.IntegerField(default=0)



# Queries start here
b1 = Bar.objects.create(value=1)
b2 = Bar.objects.create(value=2)

ForeignFoo.objects.create(bar=b1, int_field=1) # pk 1
ForeignFoo.objects.create(bar=b2, int_field=1) # pk 2
ForeignFoo.objects.create(bar=b1, int_field=1) # pk 3

queryset = ForeignFoo.objects.values('bar').annotate(total=Sum('int_field')).filter(total__gt=1)
print(queryset.first()) # None
print(queryset[0]) # Prints an object

因此,您不必使用.first,只需执行以下操作即可获得正确的结果:

result = None
sliced_queryset = queryset[:1]
if sliced_queryset:
    result = sliced_queryset[0]
print(result)

相关问题 更多 >

    热门问题