Django DateTimeField from form to UTC

Submitted 3 years, 7 months ago
Ticket #168
Views 530
Language/Framework Django
Priority Medium
Status Closed

I have a small Django app with a form, wich saves some data to the DB.

Here's the form:

class SomeForm(forms.Form):
    time = forms.DateTimeField()
...

I have a small Django app with a form, wich saves some data to the DB.

Here's the form:

class SomeForm(forms.Form):
    time = forms.DateTimeField()
...

And the view, where I save it:

class AccountAddIncome(View):
    def save(self, form):
        model = Model(
            time=form.cleaned_data['time']
        )
        model.save()

    def post(self, request, *args, **kwargs):
        form = SomeForm(request.POST)
        if form.is_valid():
            self.save(form)
            return redirect(self.success_url)
        else:
            ...

My problem is, that the Django admin says: "Note: You are 1 hour ahead of server time."
The date command on my Ubuntu (the server) says exactly the same date as my computer has.

But, when I save this object in the DB, and make the following query:

Model.objects.filter(time__lt=timezone.now())

django do not list the previously saved model for an hour. If I go to the admin, and set the time back one hour, django'll show that object.

So, my question is, what's the best practice, to manage datetime objects in django?

I want to save everything in UTC, but I cannot convert that datetime from the form to UTC.

Submitted on Sep 13, 20
add a comment

1 Answer

Verified

import pytz

from django.utils import timezone

class TimezoneMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        tzname = request.session.get('django_timezone')
        if tzname:
            timezone.activate(pytz.timezone(tzname))
        else:
            timezone.deactivate()
        return self.get_response(request)

Create a view that can set the current timezone:

from django.shortcuts import redirect, render

def set_timezone(request):
    if request.method == 'POST':
        request.session['django_timezone'] = request.POST['timezone']
        return redirect('/')
    else:
        return render(request, 'template.html', {'timezones': pytz.common_timezones})

Include a form in template.html that will POST to this view:

{% load tz %}
{% get_current_timezone as TIME_ZONE %}
<form action="{% url 'set_timezone' %}" method="POST">
    {% csrf_token %}
    <label for="timezone">Time zone:</label>
    <select name="timezone">
        {% for tz in timezones %}
        <option value="{{ tz }}"{% if tz == TIME_ZONE %} selected{% endif %}>{{ tz }}</option>
        {% endfor %}
    </select>
    <input type="submit" value="Set">
</form>

Submitted 3 years, 6 months ago


Latest Blogs