【问题标题】:python django and datetime aware objectspython django 和日期时间感知对象
【发布时间】:2014-05-06 12:44:45
【问题描述】:

我有一个 django 模型,其中一些 model.DateTimeFields 作为属性。因为用户必须能够单独添加时间和日期,并且因为我希望能够完全自定义在模板中呈现的日期和时间输入,所以我做了以下操作

class Entry(models.Model):
    title = models.CharField(max_length=40)
    body = models.CharField(max_length=10000, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    start_date = models.DateField(default=datetime.now().date())
    start_hour = models.TimeField(default=datetime.now().time())
    start = models.DateTimeField()
    end_hour = models.TimeField(default=(datetime.now()+ timedelta(minutes=45)).time())
    end = models.DateTimeField()

表格

class EntryAddForm(ModelForm):

    def __init__(self, *args, **kwargs):
        super(EntryAddForm, self).__init__(*args, **kwargs)
        self.fields['doctor'].queryset = Doctor.objects.all()


    class Meta:
        model = Entry
        exclude = ('canceled','creator', 'reason','start', 'end')
        widgets....#setting widgets here

    def save(self, commit=True):
        model = super(EntryAddForm, self).save(commit=False)
        model.start = datetime.combine(self.cleaned_data['start_date'], self.cleaned_data['start_hour'])
        model.end = datetime.combine(self.cleaned_data['start_date'], self.cleaned_data['end_hour'])


        if commit:
             model.save()

         return model

所以在保存方法中,我创建了一个新的日期时间对象,并结合了开始日期和开始时间

问题是当您将它们呈现在表单上进行编辑时。因为输入日期存储在 utc start_hour 和 end_hour 不是我从表单中保存它们的确切时间,而是晚了 3 小时(因为我住在希腊,我的设置文件中有 TIME_ZONE = Athens)。

真的有一个简单的方法可以解决这个问题,还是不使用感知对象的解决方案?

还有一点离题。 Javascript 如何知道时区偏移量。我愿意

x = new Date();
x.getTimeZoneOffset() / 60; 

我得到-3,这是正确的。如果我在我的 Ubuntu 系统中更改我的时区,我的 ubuntu 时钟会更改以匹配所选时区的时间,但上面的 javascript 代码返回相同的结果。所以javascript不会使用系统时区?

【问题讨论】:

    标签: python django datetime django-timezone


    【解决方案1】:

    它不能直接解决您的时区问题,但您不应该在模型中这样做:

    start_date = models.DateField(default=datetime.now().date())
    start_hour = models.TimeField(default=datetime.now().time())
    start = models.DateTimeField()
    

    您已经使用冗余字段污染了数据模型,只是为了更改 UI - 进行此更改的正确位置是在关联的 ModelForm(和模板)中

    Django 正是为此目的提供了https://docs.djangoproject.com/en/dev/ref/forms/widgets/#splitdatetimewidget。

    对于您的时区问题...如果您有 USE_TZ = Truein 设置,那么 Django 将根据您的设置假定来自用户输入的所有日期和时间都在 TIME_ZONE = 'Athens'... 然后它将在保存之前将这些转换为 UTC在数据库中(并在检索时将它们转换回雅典时间)。
    https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-USE_TZ

    如果您需要处理用户在不同时区提交的数据时间信息,设置USE_TZ = False 可能更容易...您的日期时间将不再有时区信息,因此您应该将所有内容标准化为 UTC 之外Django 应用程序(即在 javascript 中)

    我不确定您关于 getTimeZoneOffset 的问题的答案 - 可能您需要重新启动浏览器,然后它才能接收到对系统时区的更改?

    【讨论】:

    • 是的,但我的问题是我无法从 SplitDateTimeWidget 单独渲染每个小部件。如果我使用 SplitDateTimeWidget 作为开始,我该如何在模板中解决它。 {{form.start}} 会给我日期和时间部分。我怎样才能单独使用它们?
    • @Apostolos 您可以对小部件进行子类化,以便通过 render 方法提供您自己的自定义 HTML
    • 我可以举一个渲染函数的例子吗?
    猜你喜欢
    • 2017-06-26
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    相关资源
    最近更新 更多