简体   繁体   中英

python django and datetime aware objects

I have a django model that some model.DateTimeFields as properties. 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

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

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. I do

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

and I get -3 which is correct. 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. So javascript won't use systems timezone?

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)

Django provides https://docs.djangoproject.com/en/dev/ref/forms/widgets/#splitdatetimewidget for exactly this purpose.

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

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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