Django:过滤注释不起作用

时间:2015-05-16 03:35:58

标签: django orm

我一直遇到问题filtering annotations。模型是:

class VenueBookmark(models.Model):
    venue = models.ForeignKey(Venue)
    cost_per_guest = models.DecimalField(max_digits=19, decimal_places=2, blank=True, null=True)

class Venue(DateAwareModel):
    name = models.CharField(max_length=255)

在我看来,我基本上有:

venues = venues.annotate(min_cost=Min('venuebookmark__cost_per_guest'))
venues = venues.filter(min_cost__lte=user_input)

然而,我仍然得到>的结果。 USER_INPUT。有什么见解吗?

修改

我尝试将user_input转换为Decimal类型,但仍然得到相同的结果:

venues = venues.filter(min_cost__lte=Decimal(user_input))

这也是我从Django调试工具栏获得的大部分SQL:

SELECT "venue_search_venue"."name", MIN("bookmarks_venuebookmark"."cost_per_guest") AS "min_cost" 
FROM "venue_search_venue" 
LEFT OUTER JOIN "bookmarks_venuebookmark" ON ( "venue_search_venue"."id" = "bookmarks_venuebookmark"."venue_id" ) 
GROUP BY "venue_search_venue"."id", "venue_search_venue"."name" 
HAVING MIN("bookmarks_venuebookmark"."cost_per_guest") <= %s 
DESC LIMIT 9' - PARAMS = ("Decimal('100')",)

直接查询数据库并比较结果后,我怀疑问题是Django将user_input呈现为字符串而不是数字,例如

HAVING MIN("bookmarks_venuebookmark"."cost_per_guest") <= '100'

而不是:

HAVING MIN("bookmarks_venuebookmark"."cost_per_guest") <= 100

1 个答案:

答案 0 :(得分:0)

这是一个有趣的问题。答案很简单,您应该min更改max

venues = venues.annotate(max_cost=Max('venuebookmark__cost_per_guest'))
venues = venues.filter(max_cost__lte=max_cost)

使用示例

进行说明
venues   VenueBookmark Cost
     1       5
     1       7
  • 根据您的实际情况,如果我们将{6}作为max_cost,则结果集中会显示1个地点,因为min of VenueBookmark Cost为5且5 < 6
  • min更改max,结果中不会包含场地编号1,因为7 is not < than 6

修改

另外,请添加order_by()以清除默认排序:

venues = (venues
    .order_by()
    .annotate(min_cost=Min('venuebookmark__cost_per_guest'))
    )

group by子句上的默认排序注入排序字段。