【问题标题】:Get all match records based on their last child in Django ORM?根据他们在 Django ORM 中的最后一个孩子获取所有匹配记录?
【发布时间】:2017-04-22 08:55:12
【问题描述】:

我的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()

正如您所见,每个车手可能会在打发时间的情况下担任多个职位。
我想要一个使用 Django ORM 的查询,它给我每个司机的最后位置,假设我从客户端收到 latitudelongitude 并希望返回附近的所有汽车。


我试过这个:

 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))\

但问题是我根据他们的位置多次获得一个司机。
现在我只想让驱动程序获得他们最后的更新位置,而不是他们以前的更新位置。
谢谢

【问题讨论】:

    标签: django python-3.x django-models django-orm


    【解决方案1】:

    这是一个通过最后一个位置获得不同驱动程序的想法(这就是我理解您试图获得的原因)。

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

    然后使用distinct 以获取每个位置(最后一个)的唯一驱动程序:
    .distinct()


    还有第二个建议,让每个车手都获得最后的位置(感谢您的自动“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 的请求,从司机那里获得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()
    

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

    【讨论】:

    • 感谢您的回答。但我不想让每个职位只有司机。我想得到每个司机的最后位置。你能为此提出什么建议吗?@ppython
    • 这里,@mehrdad-pedramfar
    • 这里,@mehrdad-pedramfar,我用注释添加了第二个想法!这个应该更准确地满足您的需要!让我更新。
    • 亲爱的@ppython,现在唯一重要的是Max('person__create_date')。我希望 last_position 成为我的 Position 表的一行,而不是日期
    • 好吧,也许您真的不希望 last_position 作为数据库的一行,而是作为 Position 类的属性/方法 :) ?如果是这样......我会在我的回答中提供第三个想法。
    猜你喜欢
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 2015-09-29
    • 2019-08-05
    • 2020-06-06
    相关资源
    最近更新 更多