0

在使用 MyISAM 在 MySQL 上运行的 Django 中,我在查询集上的 Count 注释返回不正确的结果。我查看了 SQL 语句,无法确定是 MySQL 还是我的 Django 代码有问题。

Django模型:

class Resource(models.Model):
    ...
    voters = models.ManyToManyField(User, related_name="resources")

代码:

resources = Resource.objects.filter(
    ...
).annotate(
    votes=models.Count('voters')
).order_by('-votes')
print resources.query

打印的 SQL:大意是

SELECT
...,
COUNT(`app_resource_voters`.`user_id`) AS `votes`
FROM `app_resource`
...
LEFT OUTER JOIN `app_resource_voters`
ON `app_resource`.`id` = `app_resource_voters`.`resource_id`
...

在 phpMyAdmin 中测试查询返回错误的投票值。它实际上返回投票者的数量乘以 ForeignKey 关联到资源上存在的其他属性的数量(非常混乱)。Django 和 SQL 看起来是否正确,这是否意味着这是 MySQL 的问题?你会推荐换成 MyISAM 以外的东西还是换成 PostgreSQL?

4

1 回答 1

0

您可以使用另外两种解决方法。

第一个比较简单,但效率较低:在Resource模型上创建方法或属性。

class Resource(models.Model):
    ...

    @property    # or @django.utils.functional.cached_property
    def votes(self):
        return self.voters.count()

第二个是使用extra()

resources = Resource.objects.filter(
    ...
).extra(
    select={
        'votes': 'SELECT COUNT(*) FROM app_resource_voters WHERE app_resource.id = app_resource_voters.resource_id'
    },
).order_by('-votes')
于 2012-06-09T11:34:54.817 回答