我不知道怎么做......看起来很简单,但我无法做到......请给我一个提示。这是模型:
class PointOfInterest(models.Model):
name = models.CharField(max_length=100)
geom = geomodels.PointField(srid=4326)
...
class Event(models.Model):
venue = models.ForeignKey('PointOfInterest',related_name='events')
start = models.DateTimeField()
...
事件表包含许多事件,并且在同一PointOfInterest
中可能存在多个事件。我的目标是选择从我今天开始的前10个事件(过去显然有事件)。对于每个PointOfInterest
,新列表只有一个条目。所以我开始选择这些活动:
from django.db.models import Max, Min
from datetime import datetime, date, timedelta
from django.contrib.gis.measure import D
# this is my place...
pnt=Point(15.0,43.2)
# this is the date range...
start_date = datetime(date.today().year,date.today().month,date.today().day,0,0,0)
end_date = start_date + timedelta(days=30)
qs1 = Event.objects.filter(venue__geom__distance_lte=(pnt, D(km=10)))
qs2 = filter(start__range=(start_date, end_date))
qs2 = qs1.filter(start__range=(start_date, end_date))
列表现在包含所有请求的事件,但同一个地方也有多个事件......但我只需要即将发生的事件。主要问题是这个列表可能很大,我的最后一步是只获得10个即将发生的事件。我尝试使用distinct('venue')
,但后来我不能命令('开始')。所以我不知道如何继续......
我也试过反过来......
qs1 = PointOfInterest.objects.filter(geom__distance_lte=(pnt, D(km=10)))
qs2 = qs1.annotate(minDate=Min('events__start'))
qs3 = qs2.filter(minDate__range=(start_date, end_date))
这个列表给了我所有PointOfInterest
(在我的情况下为129 ...而前一个列表给了我137个事件......实际上在所选查询中有8个地方有2个事件,我需要保留每个地方只有即将到来的地方。最后我要order_by('start')
并且只保留其中的一些。)
同样在这种情况下,我尝试了很多,但没有任何效果......任何人都可以提供帮助? 感谢
修改
几乎就在那里。根据EvilX的建议,我改变了选择,但是events__start__range=(start_date, end_date)
在地点上运行,所以当我执行他建议的2个额外时,我得到了与每个地方相关的第一个事件(如果它在过去也是如此) )。我不得不稍微改变SQL查询。第一次尝试是这样的:
.extra(select={'event_pk': '
SELECT start
FROM app_event_event
AS evt
WHERE evt.venue_id=app_place_pointofinterest.id AND evt.start >= \'2014/05/04\'
ORDER BY start
LIMIT 1'})
哪个有效...然后我尝试按照django文档将参数传递给SQL查询,如下所示:
.extra(select={'event_pk': '
SELECT start
FROM app_event_event
AS evt
WHERE evt.venue_id=app_place_pointofinterest.id AND evt.start >= %s
ORDER BY start
LIMIT 1'}, params=['2014/05/04'])
但在这里我收到一个错误:StopIteration
;我尝试了不同的组合,有和没有逃脱角色,但没有任何工作...所以我需要一些更多的建议。
感谢
答案 0 :(得分:0)
尝试使用额外和两个查询。
points = PointOfInterest.objects.filter(geom__distance_lte=(pnt, D(km=10)), events__start__range=(start_date, end_date)).extra(select={'event_pk': 'SELECT event.id FROM app name_event AS event where event.venue_pk=appname_pointofinterest.id ORDER BY start LIMIT 1'}).extra(select={'event_start': 'SELECT event.start_date FROM app name_event AS event where event.venue_pk=appname_pointofinterest.id ORDER BY start LIMIT 1'}).order_by('event_start')[:10]
ids = []
for point in points:
ids.append(point.event_pk)
events = Event.objects.select_related('venue').filter(pk__in=ids)