2013-03-31 3 views
1

Я использую tastypie для получения REST API для моего приложения django. Мои модели включают в себя станцию ​​(например, железнодорожную станцию), маршрут (например, Чикаго до Сент-Луиса) и routedetail, который является промежуточной моделью для многих отношений, например. RouteDetail (станция = "Springfield-IL", маршрут = "CHI-СТЛ", arrival_time = 4:00 вечера, depart_time = 4: 5 вечера)django query on manytomany field

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) 

Мой вопрос, как я могу запросить все маршруты из Линкольн, штат Иллинойс в Сент-Луис, Миссури? Прямо сейчас я сделал что-то подобное в 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

Как ваша модель выражает существование маршрута от А до В? Это не выглядит так, как будто он содержит достаточно информации, чтобы быть в состоянии сказать.

Ближайший запрос, который я могу видеть, заключается в том, чтобы спросить, существует ли маршрут R, так что станция A находится по маршруту R, а станция B - по маршруту R, а время отправления на станции A - до времени прибытия на станция Б.

в 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; 

насколько я знаю, что нет никакого способа, чтобы выразить этот запрос в ОРМ Джанго, но вы всегда можете оформить 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. Я не включал это, так как я хотел сосредоточиться на сокращении запроса при фильтрации из и в два раза. В любом случае, ваше предложение о том, чтобы перейти на сырой SQL, представляется разумным выбором, если позже я обнаружил, что эта операция является бутылочной горловиной. Благодарю. –

Смежные вопросы