django查询manytomany字段

时间:2013-03-31 13:10:50

标签: django django-models tastypie

我正在使用tastypie为我的django应用程序获取REST API。我的模型包括车站(例如火车站),路线(例如芝加哥到圣路易斯)和路线尾部,它是许多人关系的中间模型,例如: RouteDetail(station =“Springfield-IL”,route =“CHI-STL”,arrival_time = 4.00pm,depart_time = 4:05pm)

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 个答案:

答案 0 :(得分:1)

您的模型如何表示从A到B的路线的存在?它看起来并不像我包含足够的信息就可以告诉我。

我能看到的最接近的查询是询问是否有路线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;

据我所知,在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不适用于午夜之前开始并在午夜之后结束的路线。