【问题标题】:How to add minutes to datetime in postgres via django如何通过 django 在 postgres 中为日期时间添加分钟
【发布时间】:2020-03-21 21:02:13
【问题描述】:

TL;DR:我想在 postgres 中为日期时间添加分钟,我可以想到两种方法。

考虑以下 django 模型:

from django.db import models


class AppointmentManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().annotate(
            end=models.ExpressionWrapper(
                models.F('start') + models.F('duration'),
                output_field=models.DateTimeField(),
            )
        )


class Appointment(models.Model):
    start = models.DateTimeField()
    duration = models.DurationField()

    objects = AppointmentManager()

请注意,end 是通过添加 startduration 在数据库中动态计算的。这正是我想要的。

但是,我希望持续时间的 UI 是一个数字输入,以分钟为单位给出持续时间。我目前的方法是使用以下表单字段:

import datetime
from django import forms


class MinutesField(forms.DurationField):
    widget = forms.NumberInput

    def prepare_value(self, value):
        if isinstance(value, datetime.timedelta):
            return int(value.total_seconds() / 60)
        return value

    def to_python(self, value):
        if value in self.empty_values:
            return None
        if isinstance(value, datetime.timedelta):
            return value
        if isinstance(value, str):
            value = int(value, 10)
        return datetime.timedelta(seconds=value * 60)

这对我来说看起来有点脆弱。是否也可以将持续时间存储为整数并动态转换为持续时间?像这样的:

class AppointmentManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().annotate(
            end=models.ExpressionWrapper(
                models.F('start') + models.Func(models.F('duration'), function='minutes'),
                output_field=models.DateTimeField(),
            )
        )

class Appointment(models.Model):
    start = models.DateTimeField()
    duration = models.IntegerField()

    objects = AppointmentManager()

【问题讨论】:

    标签: django postgresql datetime orm


    【解决方案1】:

    this answer找到解决方案:

    class AppointmentManager(models.Manager):
        def get_queryset(self):
            return super().get_queryset().annotate(
                end=models.ExpressionWrapper(
                    models.F('start') + datetime.timedelta(seconds=60) * models.F('duration'),
                    output_field=models.DateTimeField(),
                )
            )
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 2016-02-19
    • 2016-09-04
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多