1

看法:

transfer_details = TransferDetail.objects.filter(user=request.user).select_related('transfermethod_set')

print transfer_details.filter(method__name='PayPal')

楷模:

class TransferMethod(models.Model):
    name = models.CharField(max_length=30)
    ...


class TransferDetail(models.Model):
    data = models.TextField()
    ...
    method = models.ForeignKey(TransferMethod)
    user = models.ForeignKey(User)

我希望使用第一行的 transfer_details QuerySet 而无需进一步的数据库调用。

我错过了什么?

更新 1

所以我发现当我有这两行时没有额外的查询:

    x = transfer_details.filter(method__name='PayPal')
    x2 = transfer_details.filter(method__name='Something')

但是当我添加以下两行时,它会进行 2 个数据库查询:

    list(x[:1])
    list(x2[:1])

幕后发生了什么以及如何避免额外的电话?

更新 2

我试过了:

transfer_details.get(method__name='PayPal').data
...

它还进行了两个查询。

4

1 回答 1

1

它应该是正确的(假设您还想在一个查询中获取用户数据):

transfer_details = TransferDetail.objects.filter(
    user=request.user).select_related('method', 'user')

您不需要选择method,因为当您过滤它时,print transfer_details.filter(method__name='PayPal')它应该会自动被选中。当您调用print TansferDetail's__unicode__时,将被调用,因此额外的原因可能是您正在那里输出一些其他相关数据(例如,来自User模型,应该用上面的代码解决......)。

要回答您编辑的问题:如果您调用查询集,则查询list集会被评估,这意味着进行了实际查询。

不知道您是否request.user在之前的代码中访问过,但如果不是这种情况,则第二个查询可能是获取当前请求的用户的结果。

于 2013-06-08T00:03:58.523 回答