获取间接路线Django ORM

时间:2016-09-09 07:57:21

标签: django orm

我正在制作一个总线路由应用程序的后端,我被困住了这个特殊的部分。首先,这是我的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

0 个答案:

没有答案