给予关系秩序排序

syn*_*nic 7 django django-orm

鉴于以下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)
Run Code Online (Sandbox Code Playgroud)

Beacon模型是与房间的蓝牙信标关系.

我想选择与给定uuid, major, minor组合匹配的所有房间.

问题是,我想通过距离我最近的灯塔订购房间.因此,我需要能够动态地为每个信标分配一个值,然后按它排序.

Django ORM可以实现吗?在Django 1.8中?

注意 - 我将事先了解信标的顺序,我将使用它们在查询字符串中传递的顺序.因此传递的第一个信标(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')
Run Code Online (Sandbox Code Playgroud)

syn*_*nic 0

看起来这样有效:

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))
Run Code Online (Sandbox Code Playgroud)