根据 Django ORM 中的最后 child 获取所有匹配记录?

Get all match records based on their last child in Django ORM?

我的 models.py 中有这两个 类 :

class BaseObject(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    create_date = models.DateTimeField(auto_now_add=True)
    update_date = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['create_date']


class Person(BaseObject):

    first_name = models.CharField(max_length=30, null=True, blank=True)
    last_name = models.CharField(max_length=30, null=True, blank=True)
    phone_number = models.CharField(max_length=15,unique=True)
    birthday = models.DateField(null=True, blank=True)
    email = models.EmailField(null=True, blank=True)

class Driver(Person):
    balance = models.PositiveIntegerField(null=True, blank=True)
    score = models.PositiveIntegerField(null=True, blank=True)

class Position(BaseObject):
    person = models.ForeignKey(Driver, on_delete=models.CASCADE)
    latitude = models.FloatField()
    longitude = models.FloatField()

大家可以看到每个driver随着时间的流逝可能会有好几个位置。
我想要一个使用 Django ORM 的查询,它给我每个 driver 的最后位置,想象一下我从客户那里收到 latitudelongitude,并希望 return 所有汽车近.


我试过了:

 radius = 5

 drivers = Driver.objects.filter(position__latitude__range=(data.get('latitude') - radius, data.get('latitude') + radius))\
                         .filter(position__longitude__range=(data.get('longitude') - radius, data.get('longitude') + radius))\

但问题是我根据他们的位置多次得到一个driver。
现在我只想获得 drivers 及其上次更新位置,而不是之前的更新位置。
谢谢

这是一个让 Drivers(这就是为什么我知道你试图获得)与它的最后一个位置不同的想法。

首先,按Driver个位置排序,从最后一个到第一个。
.order_by('-person__create_date',)

然后使用distinct以便每个位置(最后一个)仅获得Driver:
.distinct()


这是第二个建议,让每个 driver 都处于最后位置(感谢你的自动 'create_date' 和 Django Annotate):

my_drivers = Driver.objects.all().annotate(last_position=Max('person__create_date'))

my_drivers[0].last_position
datetime.datetime(2016, 11, 17, 14, 25, tzinfo=<UTC>)

此处,my_drivers 查询集中的每个项目都有一个 last_position 属性。


最后,根据@mehrdad-pedramfar 的请求,一个从 Driver.

得到 last_position 的想法
class Driver(Person):
    balance = models.PositiveIntegerField(null=True, blank=True)
    score = models.PositiveIntegerField(null=True, blank=True)

    def get_last_position(self):
        return Position.object.filter(person=self).order_by('-create_date').first()

我还没有针对您的代码进行过尝试,但想法就在这里。每次调用它都会花费一个数据库调用。 结果是最后一个 Position object for the current Driver :)