【问题标题】:Equivalent of objects.latest() in App Engine等效于 App Engine 中的 objects.latest()
【发布时间】:2010-09-16 21:03:55
【问题描述】:

使用 AppEngine 获取最新插入的对象的最佳方法是什么? 我知道在 Django 中可以使用

MyObject.objects.latest()

在 AppEngine 中我希望能够做到这一点

class MyObject(db.Model):
  time = db.DateTimeProperty(auto_now_add=True)

# Return latest entry from MyObject.
MyObject.all().latest()

有什么想法吗?

【问题讨论】:

    标签: python django google-app-engine


    【解决方案1】:

    您最好的选择是直接在 MyObject 上实现 latest() 类方法并调用它

    latest = MyObject.latest()
    

    其他任何事情都需要猴子修补内置的Query 类。

    更新

    我想我会看到实现这个功能会有多难看。如果您真的希望能够调用MyObject.all().latest(),可以使用以下混合类:

    class LatestMixin(object):
        """A mixin for db.Model objects that will add a `latest` method to the
        `Query` object returned by cls.all(). Requires that the ORDER_FIELD
        contain the name of the field by which to order the query to determine the
        latest object."""
    
        # What field do we order by?
        ORDER_FIELD = None
    
        @classmethod
        def all(cls):
            # Get the real query
            q = super(LatestMixin, cls).all()
            # Define our custom latest method
            def latest():
                if cls.ORDER_FIELD is None:
                    raise ValueError('ORDER_FIELD must be defined')
                return q.order('-' + cls.ORDER_FIELD).get()
            # Attach it to the query
            q.latest = latest
            return q
    
    # How to use it
    class Foo(LatestMixin, db.Model):
        ORDER_FIELD = 'timestamp'
        timestamp = db.DateTimeProperty(auto_now_add=True)
    
    latest = Foo.all().latest()
    

    【讨论】:

    • 嘿Will,我想了想,但是我不能在不初始化对象的情况下调用这个函数。有没有办法在没有对象初始化的情况下调用它。 ?
    • 当然可以,如果您将其定义为类方法(使用@classmethod 装饰器)。
    • 太棒了!你刚刚给我上了一课:)
    • 我实际上建议这样做,而不是使用我刚刚添加到答案中的愚蠢的概念证明混合。
    【解决方案2】:

    MyObject.all() 返回 Query class 的一个实例

    按时间排序结果:

    MyObject.all().order('-time')
    

    因此,假设至少有一个条目,您可以通过以下方式直接获取最新的 MyObject:

    MyObject.all().order('-time')[0]
    

    MyObject.all().order('-time').fetch(limit=1)[0]
    

    【讨论】:

    • 或 MyObject.all().order('-time').get()
    • MyObject.all().order('-time')[0] 应该避免,因为即使你只想要一个,它也会获取一批 20 个实体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 2017-08-20
    • 2015-12-31
    • 2012-04-12
    • 2014-07-18
    相关资源
    最近更新 更多