简体   繁体   English

python django和日期时间感知对象

[英]python django and datetime aware objects

I have a django model that some model.DateTimeFields as properties. 我有一个django模型,有些model.DateTimeFields作为属性。 Because the user had to be able to seperatelly add time and date, and because I wanted to be able to fully customize the date and time inputs that render in the template I did the following 因为用户必须能够单独添加时间和日期,并且因为我希望能够完全自定义在模板中呈现的日期和时间输入,所以我执行了以下操作

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

The form 表格

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

So in the save method I create a new date time object with the combination of start date and start hour 因此,在save方法中,我创建了一个新的日期时间对象,其中包含开始日期和开始时间的组合

The problem is when you present them on a form for editing. 问题是当您将它们呈现在表单上进行编辑时。 Because entry dates are stored in utc start_hour and end_hour are not the exact time from when I saved them from the form but 3 hours behind (because I live in Greece and I have TIME_ZONE = Athens on my settings file). 因为输入日期存储在utc start_hour中,而end_hour不是从我从表单中保存它们但落后3小时的确切时间(因为我住在希腊,我的设置文件中有TIME_ZONE = Athens)。

Is there really an easy way to get by this problem or is the solution not to use aware objects? 是否真的有一种简单的方法可以解决这个问题,或者解决方案是不使用感知对象?

And one more little off topic. 还有一个小题目。 How does Javascript know timezone offset. Javascript如何知道时区偏移量。 I do 我做

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

and I get -3 which is correct. 我得到-3这是正确的。 If I change my time zone in my Ubuntu system, my ubuntu clock changes to match the time of the selected timezone, but the above javascript code returns the same result. 如果我在我的Ubuntu系统中更改我的时区,我的ubuntu时钟会更改以匹配所选时区的时间,但上面的javascript代码会返回相同的结果。 So javascript won't use systems timezone? 所以javascript不会使用系统时区?

It doesn't directly address your timezone issue, but you should not do this in the model: 它不直接解决您的时区问题,但您不应该在模型中执行此操作:

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

You have polluted your data model with redundant fields just for purpose of changing the UI - the proper place to make this change is in the associated ModelForm (and templates) 您已经使用冗余字段污染了数据模型,仅仅是为了更改UI - 进行此更改的正确位置在关联的ModelForm(和模板)中

Django provides https://docs.djangoproject.com/en/dev/ref/forms/widgets/#splitdatetimewidget for exactly this purpose. Django正是为了这个目的提供了https://docs.djangoproject.com/en/dev/ref/forms/widgets/#splitdatetimewidget

For you timezone problem... if you have USE_TZ = True in settings then Django will assume all dates and times coming from user input are in TIME_ZONE = 'Athens' per your settings... it will then convert these to UTC before saving in the db (and will convert them back to Athens time when retrieving). 对于你的时区问题...如果您在设置中有USE_TZ = True ,那么Django将假设来自用户输入的所有日期和时间都是根据您的设置在TIME_ZONE = 'Athens' ...然后它将在保存之前将它们转换为UTC db(并在检索时将它们转换回雅典时间)。
https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-USE_TZ https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-USE_TZ

If you need to deal with data-time information submitted by users in a variety of timezone it may be easier to set USE_TZ = False ...your datetimes will no longer have timezone info, so you should normalise everything to UTC outside of the Django app (ie in the javascript) 如果您需要处理用户在各种时区提交的数据时间信息,可能更容易设置USE_TZ = False ...您的日期时间将不再USE_TZ = False区信息,因此您应该将所有内容规范化为Django之外的UTC应用程序(即在JavaScript中)

I'm not sure the answer to your question about getTimeZoneOffset - possibly you need to restart your browser before it picks up change to the system timezone? 我不确定你关于getTimeZoneOffset的问题的答案 - 可能你需要重新启动浏览器才能获得对系统时区的更改?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM