我正在制作一个总线路由应用程序的后端,我被困住了这个特殊的部分。首先,这是我的models.py文件。
from __future__ import unicode_literals
from colorfield.fields import ColorField
from django.db import models
# Create your models here.
class BusStop(models.Model):
name = models.CharField(max_length=100, blank=False)
lat = models.DecimalField(
max_digits=9, decimal_places=6, blank=True, null=True)
long = models.DecimalField(
max_digits=9, decimal_places=6, blank=True, null=True)
isDisabled = models.BooleanField(default=False)
stop_info = models.TextField(blank=True, null=True)
def __unicode__(self):
return self.name
class BusRoute(models.Model):
name = models.CharField(max_length=100, blank=False)
start_stop = models.ForeignKey(BusStop, related_name="routes_start")
end_stop = models.ForeignKey(BusStop, related_name="routes_end")
path = models.ManyToManyField(BusStop, through="BusRoutePath")
def route_path(self):
return ",".join([str(p) for p in self.path.all()])
def __unicode__(self):
return self.name
class BusRoutePath(models.Model):
"""
Path of the route with ordering of bus stops.
"""
route = models.ForeignKey(BusRoute)
stop = models.ForeignKey(BusStop)
order = models.IntegerField("Bus stop order") # This should start with 0
duration = models.DurationField(blank=True, null=True)
fare_bt_stops = models.DecimalField(
max_digits=6, decimal_places=2, blank=False)
def __unicode__(self):
return "%s-%s-%d" % (self.route.name, self.stop.name, self.order)
class Bus(models.Model):
class Meta:
verbose_name = 'Bus'
verbose_name_plural = 'Buses'
color = ColorField(default='#FF0000')
number = models.CharField(max_length=50, blank=True, null=True)
bus_info = models.TextField(blank=True, null=True)
def __unicode__(self):
return self.number
class Ride(models.Model):
route = models.ForeignKey(BusRoute)
bus = models.ForeignKey(Bus)
departure = models.DateTimeField(blank=False)
schedule_info = models.TextField()
status = models.CharField(max_length=100, default="On Time",
choices=[('On Time', 'On Time'),
('Delayed', 'Delayed'),
('Cancelled', 'Cancelled')])
我已编写此查询以查找将在两个位置之间的路由列表。
queryset = queryset.filter(path__in=[origin_stop]).filter(
path__in=[destination_stop])
然后我根据停止的顺序检查路线是否有效,因为只有当原点停止的订单号在目的地停止点之前时,路线才有效。
def check_if_valid_route(route, origin_stop, destination_stop):
releated_stops = BusRoutePath.objects.filter(route=route).select_related()
related_origin = releated_stops.get(stop=origin_stop)
related_destination = releated_stops.get(stop=destination_stop)
return related_origin.order < related_destination.order
所以我的问题是我能做得比这更好吗?现在我只给出一个直接路由列表,然后验证它是否有效。我可以用一个查询来完成吗?
我的第二个问题是,如果我找不到直接路线,我可以给出一份间接路线清单吗?
这是我在views.py中的类,用于返回按其来源和目的地过滤的路由列表。
class RouteList(generics.ListCreateAPIView):
queryset = BusRoute.objects.all()
serializer_class = BusRouteSerializer
def get_queryset(self):
queryset = BusRoute.objects.all()
origin = self.request.query_params.get('origin', None)
destination = self.request.query_params.get('destination', None)
if origin is not None and destination is not None:
try:
origin_stop = BusStop.objects.get(name=origin)
destination_stop = BusStop.objects.get(name=destination)
queryset = queryset.filter(path__in=[origin_stop]).filter(
path__in=[destination_stop])
temp = []
for route in queryset:
if check_if_valid_route(route, origin_stop, destination_stop):
temp.append(route)
queryset = temp
if(len(queryset)) == 0:
raise NotFound(
"We were unable to find any direct routes between these stops")
except BusStop.DoesNotExist:
raise NotFound("The origin or destination does not exist")
return queryset