2013-03-31 87 views
1

我正在使用tastypie爲我的django應用程序獲取REST API。我的模型包括車站(例如火車站),路線(例如芝加哥到聖路易斯)和路線尾巴,這是許多關係的中間模型,例如, RouteDetail(站= 「斯普林菲爾德-IL」 路線= 「CHI-STL」,ARRIVAL_TIME = 16:00,depart_time = 4:下午5點)django查詢manytomany字段

class Station(models.Model): 
    name = models.CharField(max_length=10, unique=True) 

class Route(models.Model): 
    name = models.CharField(max_length=10, unique=True) 
    stations = models.ManyToManyField(Station, through='RouteDetail') 

class RouteDetail(models.Model): 
    station = models.ForeignKey(Station) 
    route = models.ForeignKey(Route) 
    arrival_time = models.TimeField(blank=True, null=True) 
    depart_time = models.TimeField(blank=True, null=True) 

我的問題是我怎麼可以查詢從林肯,IL的所有路由去密蘇里州聖路易斯? 現在我在tastypie中做了這樣的工作,但是有一種方法可以在一個查詢中完成它?

from_station = request.GET.get('from', None) 
to_station = request.GET.get('to', None) 
semi_filtered = super(RouteResource, self).apply_filters(request, applicable_filters) 
return semi_filtered.filter(stations__name=from_station).filter(stations__name=to_station) 

回答

1

您的模型如何表示路由從A到B的存在?它並不看我,好像它包含足夠的信息以便能夠說明。

我可以看到的最接近的查詢方法是詢問是否存在路線R,使得站點A在路線R上,而站點B在路線R上,並且站點A的出發時間在到達時間點之前站B.

在SQL這將是:

SELECT * FROM myapp_route R 
JOIN myapp_routedetail A ON A.station_id = from_station AND A.route_id = R.id 
JOIN myapp_routedetail B ON B.station_id = to_station AND B.route_id = R.id 
WHERE A.depart_time < B.arrival_time; 

據我知道有沒有辦法表達Django的ORM此查詢,但你總是可以發出raw SQL query

Route.objects.raw(''' 
    SELECT * FROM myapp_route R 
    JOIN myapp_routedetail A ON A.station_id = %s AND A.route_id = R.id 
    JOIN myapp_routedetail B ON B.station_id = %s AND B.route_id = R.id 
    WHERE A.depart_time < B.arrival_time 
    ''', [from_station.id, to_station.id]) 

但請注意:條件A.depart_time < B.arrival_time不適用於午夜前開始並在午夜後完成的路線。

+0

你是對的我需要比較arrival_time來確定它是否是A到B.我沒有包括這個,因爲我想專注於減少查詢過濾from和to兩次。無論如何,如果我後來發現這個操作是瓶頸的話,那麼你對原始SQL的建議似乎是合理的選擇。謝謝。 –