Py学习  »  Django

在django中使用annotate的日期时间差

Ptrik • 6 年前 • 2085 次点击  

我有一个模特,

class Event(models.Model):
    name = models.CharField(max_length=100)
    start = models.DateTimeField()
    end = models.DateTimeField()

    @property
    def diff_days(self):
        return (self.end - self.start).days

我怎么才能拿到 diff_days 结果使用 .annotate() 在数据库级别?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/37932
文章 [ 3 ]  |  最新文章 6 年前
5parkp1ug
Reply   •   1 楼
5parkp1ug    7 年前

或者你可以直接用姜戈的 Extract 函数来提取不同的天数。那么你的查询集应该是-

from django.db.models.functions import ExtractDay
event_queryset = Event.objects.annotate(diff_days=ExtractDay(F('end')-F('start')))
Higor Rossato
Reply   •   2 楼
Higor Rossato    7 年前

不幸的是,您不能。您只能注释db字段。这篇文章可能对你有帮助 Django annotate model custom method

JPG
Reply   •   3 楼
JPG    7 年前

因为你在使用 MYSQL 5.6 ,你可以使用MySQL TIMESTAMPDIFF(...) 功能。

我的建议是,通过继承 django.db.models.expressions.Func 类为,

class Format(dict):
    def __missing__(self, key):
        return '%(' + key + ')s'


class TIMESTAMPDIFF(Func):
    def __init__(self, start, end, unit='days'):
        extra = {}
        expressions = [start, end]
        extra['output_field'] = IntegerField()
        self.template = self.template % Format({"unit": unit})
        super().__init__(*expressions, **extra)

    function = 'TIMESTAMPDIFF'
    template = "%(function)s(%(unit)s, %(expressions)s)"



因此,annotation查询将为,

event_queryset = Event.objects.annotate(days=TIMESTAMPDIFF(F('start'), F('end'), unit='DAY' ))
参考文献 : How to implement TIMESTAMPDIFF() of MYSQL in Django