Django以非显着的顺序排序ManyToMany字段

时间:2016-07-20 20:46:52

标签: python django python-3.x orm manytomanyfield

我有两个模型如下:

class Stop(models.Model):
    """
    Showing bus stops in İzmir.
    """

    code = models.PositiveIntegerField(
        unique=True,
        primary_key=True,
        verbose_name="Code"
    )

    label = models.CharField(
        null=False,
        blank=False,
        max_length=64,
        verbose_name="Label"
    )

    coor = ArrayField(
        models.FloatField(),
        size=2,
        verbose_name="Coordination"
    )

    class Meta:
        verbose_name = "Stop"
        verbose_name_plural = "Stops"
        ordering = ["label"]

    def __str__(self):
        return self.label

class Route(models.Model):
    """
    Bus routes of İzmir.
    """

    code = models.PositiveSmallIntegerField(
        unique=True,
        primary_key=True,
        verbose_name="Code"
    )

    stops = models.ManyToManyField(
        Stop,
        null=True,
        blank=True,
        related_name="routes",
        verbose_name="Stops"
    )

    terminals = ArrayField(
        models.CharField(
            null=False,
            blank=False,
            max_length=32,
        ),
        size=2,
        default=[],
        verbose_name="Terminals"
    )

    departure_times = ArrayField(
        ArrayField(
            models.TimeField(
                null=False,
                blank=False
            ),
            null=True,
            default=[]
        ),
        default=[],
        size=6,
        verbose_name="Departure Times"
    )

    class Meta:
        verbose_name = "Route"
        verbose_name_plural = "Routes"
        ordering = ["code"]

    def __str__(self):
        return "{}: {} - {}".format(str(self.code), self.terminals[0], self.terminals[1])

正如您所看到的,RouteManyToManyFields,需要Stop个实例。

我把实例放在一个脚本中,它会丢弃几个网页,似乎我会使用crontab来保持它们的更新。在我正在抓取的数据中,Stop对象被排序。问题是,没有重要的过滤器来排序,例如一个Stop实例接连不断。

Django(或Django Rest Framework)按字母顺序返回Stop个实例的Route个实例,例如

{
    "code": 285,
    "terminals": [
        "EVKA 1",
        "KONAK"
    ],
    "stops": [
        40586,
        40633,
        12066,
        40645,
        40627,
        40647,
        40588,
        40592,
        40623,
        40016,
        40506,
        40508,
        40528,
        40462,
        40631,
        40014,
        40619,
        40530,
        12060,
        40661,
        40504,
        40488,
        40653,
        40590,
        40512,
        40464,
        10240,
        10036,
        12068,
        40514,
        40510,
        40658,
        40002,
        40649,
        12070,
        40004,
        40010,
        40656,
        12064,
        40614,
        40012
    ],
    ...
}

其中stops[0]返回以Stop开头的A个实例并对其进行排序。

那么,有没有办法像Python中的list那样订购?比如,没有重要意义,你只需追加到最后并返回。

环境

  • python 3.5.1
  • django 1.9.7
  • djangorestframework 3.3.3
  • psycopg2 2.6.2
  • postgresql 9.5

1 个答案:

答案 0 :(得分:1)

position的{​​{1}}相对于stop,例如Route可以是第一站,route 1可以是第二站等等。所以这是一个完美的示例,您需要更多关于route 2关系的metadata。 Djagno解决了这个问题,方法是让Intermediate Table提供两个Route-Stop以及关系所需的ForeignKey

metadata

现在,当您获得class Stop(models.Model): #... class Route(models.Model): #... stops = models.ManyToManyField(Stop, through='RouteStop', blank=True, related_name="routes", verbose_name="Stops") class RouteStop(models.Model): stop = models.ForeignKey(Stop) route = models.ForeignKey(Route) position = models.PositiveSmallIntegerField() class Meta: unique_together = (("stop", "route"),) 时,您可以按Routes订购route.stops,例如:

RouteStop.position