这是我的django型号:
class Author (models.Model):
name = models.CharField(max_length=255)
removed = models.BooleanField(default=False)
class Image (models.Model):
author = models.ForeignKey(Author)
name = models.CharField(max_length=255)
height = models.PositiveIntegerField()
width = models.PositiveIntegerField()
基本上,我需要选择每个未被移除的作者以及有5个或更少高度等于100的图像的作者。
我使用MySQL,这是版本信息:
mysql Ver 14.12 Distrib 5.0.67
当然,它看起来像这样:
Author.objects.filter(removed=False).extra(select={
'imgcount': """SELECT COUNT(*)
FROM ormtest_image
WHERE height=100 AND
ormtest_image.author_id=ormtest_author.id"""
}).filter(imgcount__lte=5)
它不起作用:“FieldError:无法将关键字'imgcount'解析为字段。选项包括:id,image,name,removed”
好的,让我们试试额外方法的论点:
Author.objects.filter(removed=False).extra(select={
'imgcount': """SELECT COUNT(*)
FROM ormtest_image
WHERE height=100 AND
ormtest_image.author_id=ormtest_author.id"""
}, where=['imgcount <= 5'])
它不起作用:“OperationalError:(1054,'where子句'中的未知列'imgcount')”,因为要过滤MySQL中计算字段的数据,你必须使用HAVING子句。
有什么想法吗?
我用Django 1.1和trunk的最新版本进行了测试。
到目前为止,我使用了这个黑客:
Author.objects.filter(removed=False).extra(select={
'imgcount': """SELECT COUNT(*)
FROM ormtest_image
WHERE height=100 AND
ormtest_image.author_id=ormtest_author.id"""
}, where=['1 HAVING imgcount <=5'])
P.S。 YAML夹具:
---
- model: ormtest.author
pk: 1
fields:
name: 'Author #1'
removed: 0
- model: ormtest.author
pk: 2
fields:
name: 'Author #2'
removed: 0
- model: ormtest.author
pk: 3
fields:
name: 'Author #3'
removed: 1
- model: ormtest.image
pk: 1
fields:
author: 1
name: 'Image #1'
height: 100
width: 100
- model: ormtest.image
pk: 2
fields:
author: 1
name: 'Image #2'
height: 150
width: 150
- model: ormtest.image
pk: 3
fields:
author: 2
name: 'Image #3'
height: 150
width: 100
- model: ormtest.image
pk: 4
fields:
author: 2
name: 'Image #4'
height: 150
width: 150
答案 0 :(得分:2)
好的,未经测试,因为我没有您的数据 - 这是怎么回事:
Author.objects.filter(removed=False).select_related('image').filter(image__height=100).annotate(count_of_images=Count('image')).filter(count_of_images__lte=5)
编辑:
那几乎把你带走了。问题与外部联接有关......我认为这是应该为您完成的最终版本:
Author.objects.filter(removed=False).select_related('image').filter(Q(image__height=100) | Q(image__height__isnull=True)).annotate(count_of_images=Count('image')).filter(count_of_images__lte=5)
那里有Q(image__height=100) | Q(image__height__isnull=True)
诀窍。它将获得具有高度为100 OR 作者的作者,其图像高度为null(意味着他们没有关联的图像)。
PS。谢谢你的问题......这实际上比我原先想象的更具挑战性,我在尝试测试过程中学到了一些很酷的技巧!
哎哟......我用sqlite3测试了我的最后一个解决方案。我没有用于测试的MySQL实例...: - (
让我思考另一种选择。
但是 - 是的 - 如果它在sqlite中工作,它应该在MySQL中工作;我会将其报告为错误。
答案 1 :(得分:0)
据我所知,你没有使用计数值,除了过滤那些大于1的作者。如果是这样,你可以用ORM代码完全用简单的查询来完成:
Author.objects.filter(removed=False, image__height__gte=100)