根据 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 的最后位置,想象一下我从客户那里收到 latitude
和 longitude
,并希望 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
:)
我的 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 的最后位置,想象一下我从客户那里收到 latitude
和 longitude
,并希望 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
:)