给关系排序依据
Giving relations an order to sort by
给定以下 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
模型是与房间的蓝牙信标关系。
我想 select 所有匹配给定 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')
如果您已经知道信标的顺序,则无需在 QuerySet 本身内进行排序。取一个名为 beacon_list
的有序列表,其中按顺序包含信标的主键,例如索引 0 处的项目是最近的信标的主键,索引 1 处的项目是第二个最近的信标的 PK,等等。然后使用列表理解:
ordered_rooms = [Room.objects.get(pk=x) for x in beacon_list]
您也不必使用 PK,您可以使用任何能识别数据库中给定对象的东西,例如name
字段。
看起来像这样:
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))
给定以下 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
模型是与房间的蓝牙信标关系。
我想 select 所有匹配给定 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')
如果您已经知道信标的顺序,则无需在 QuerySet 本身内进行排序。取一个名为 beacon_list
的有序列表,其中按顺序包含信标的主键,例如索引 0 处的项目是最近的信标的主键,索引 1 处的项目是第二个最近的信标的 PK,等等。然后使用列表理解:
ordered_rooms = [Room.objects.get(pk=x) for x in beacon_list]
您也不必使用 PK,您可以使用任何能识别数据库中给定对象的东西,例如name
字段。
看起来像这样:
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))