Дать отношениям порядок сортировки - PullRequest
0 голосов
/ 22 сентября 2018

С учетом следующих моделей Django:

class Room(models.Model):
    name = models.CharField(max_length=20)

class Beacon(models.Model):
    room = models.ForeignKey(Room)
    uuid = models.UUIDField(default=uuid.uuid4)
    major = models.PostiveIntegerField(max_value=65536)
    minor = models.PositiveIntegerField(max_value=65536)

Модель Beacon представляет собой связь маяка Bluetooth с комнатой.

Я хочу выбрать все комнаты, соответствующие данному uuid, major, minor комбинация.

Суть в том, что я хочу заказать номера у ближайшего ко мне маяка.Из-за этого мне нужно иметь возможность динамически присваивать значение каждому маяку, а затем сортировать по нему.

Возможно ли это с Django ORM?В Django 1.8?

NOTE - я заранее буду знать порядок расположения маяков, я буду использовать порядок их передачи в строке запроса.Итак, первый пройденный маяк (uuid, major, minor) должен соответствовать первой комнате, возвращаемой Room QuerySet

Я предполагаю что-то подобное, хотя знаю, что это не сработает:

beacon_order = [
    beacon1 = 1,
    beacon0 = 2,
    beacon3 = 3,
]

queryset = Room.objects.annotate(beacon_order=beacon_order).\
               order_by('beacon_order')

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Похоже, это работает:

from django.db.models import Case, Q, When

beacons = request.query_params.getlist('beacon[]')
query = Q()
order = []

for pos, beacon in enumerate(beacons):
    uuid, major, minor = beacon.split(':')

    query |= Q(
        beacon__uuid=uuid,
        beacon__major=major,
        beacon__minor=minor,
        )

    order.append(When(
        beacon__uuid=uuid,
        beacon__major=major,
        beacon__minor=minor,
        then=pos,
        ))

rooms = Room.objects.filter(query).order_by(Case(*order))
0 голосов
/ 22 сентября 2018

Если вы уже знаете порядок маяков, нет необходимости сортировать внутри самого QuerySet.Возьмите упорядоченный список с именем beacon_list, который содержит первичные ключи маяков по порядку, например, элемент с индексом 0 является первичным ключом ближайшего маяка, элемент с индексом 1 является PK второго ближайшего маяка и т. Д. Затем используйте списокпонимание:

ordered_rooms = [Room.objects.get(pk=x) for x in beacon_list]

Вам также не нужно использовать ПК, вы можете использовать все, что идентифицирует данный объект в базе данных, например, поле name.

...