Django基于每个对象时区保存datetime [英] Django saving datetime based on per object timezone

查看:134
本文介绍了Django基于每个对象时区保存datetime的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于大多数使用TIME_ZONE和USE_TZ设置保存数据时间的应用程序都可以。我的问题是,如何完成使用UTC的datetime保存模型,但是datetime设置为使转换回输入时区的用户是正确的?模型,视图,形式和html给出如下。如果USES_TZ = False在settings.py文件中,此代码将会起作用,但我希望保留该项目中其他所有内容的时区。

For the majority of my application saving datetimes with the TIME_ZONE and USE_TZ settings are fine. My question is, how can I accomplish saving a model with a datetime that is in UTC, but the datetime is set so that converting back to the users inputted timezone is correct? Model, view, form and html given below. This code will work if USE_TZ = False in the settings.py file, but I would like to keep the timezone for everything else in the project.

型号: >

Model:

class TZTestModel(models.Model):
    timezone = TimeZoneField()
    dt = models.DateTimeField()

查看:

class TZTestView(LoginRequiredMixin, TemplateView):
    template_name = "tz_test.html"

    def get_context_data(self, **kwargs):
        return {
            'form': self.form
        }

    def dispatch(self, request, *args, **kwargs):
        self.form = TZTestForm(self.request.POST or None)
        return super(TZTestView, self).dispatch(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        if self.form.is_valid():
            self.form.save()
        return self.render_to_response(self.get_context_data())

形式:

class TZTestForm(forms.ModelForm):
    class Meta:
        model = TZTestModel

    def clean(self):
        timezone = self.cleaned_data['timezone']
        dt = self.cleaned_data['dt']
        dt = timezone.localize(dt)
        self.cleaned_data['dt'] = pytz.UTC.normalize(dt.astimezone(pytz.UTC))
        return self.cleaned_data

模板:

<html>
    <body>
        <form method="post">
            {% csrf_token %}
            {{ form }}
            <input type="submit">
        </form>
    </body>
</html>

示例:

我想能够进入美国/阿拉斯加的时区,今天的时间是13:00,除非是UTC值,那么可以转换回美国/阿拉斯加并获得正确的值。

I would like to be able to enter a timezone of 'US/Alaska' and a datetime of today at 13:00, save that as it's UTC value, then be able to convert back to 'US/Alaska' and get the correct value.

本质上,我试图在不同于我的应用程序的时区中保存一个模型的日期时间,其中用户以与datetime指定的相同形式指定时区。 p>

Essentially I am trying to save one model's datetime in a different timezone than my application, where the timezone is specified by the user in the same form that the datetime is specified in.

推荐答案

我有与对象级时区相同的问题。

I have had the same issue with object-level timezones.

我发现此博客条目。这不是完美的,但它的作品!并不是太复杂。加上处理管理员的处理方式。

I found this blog entry. It's not perfect but it works! and is not too complex. Plus handling the Admin is dealt with.

在此处粘贴代码段:

def view(request):

    if request.method == 'POST':
        tz_form = TimeZoneForm(request.POST)
        if tz_form.is_valid():
            tz = tz_form.cleaned_data['event_time_zone']
            timezone.activate(tz)
            # Process the full form now
    else:
        # assuming we have an event object already
        timezone.activate(event.event_time_zone)
        # Continue to create form for display on the web page



在管理列表视图中正确显示



Displaying correctly in the Admin list view

class EventAdmin(admin.ModelAdmin):
    list_display = [..., 'event_datetime_in_timezone', ...]

    def event_datetime_in_timezone(self, event):
        """Display each event time on the changelist in its own timezone"""
        fmt = '%Y-%m-%d %H:%M:%S %Z'
        dt = event.event_datetime.astimezone(pytz_timezone(event.event_time_zone))
        return dt.strftime(fmt)
    event_datetime_in_timezone.short_description = _('Event time')



正确解释Admin Add视图中的datetimne



Interpret correctly the datetimne in Admin Add view

class EventAdmin(admin.ModelAdmin):
    # ...

    # Override add view so we can peek at the timezone they've entered and
    # set the current time zone accordingly before the form is processed
    def add_view(self, request, form_url='', extra_context=None):
        if request.method == 'POST':
            tz_form = TimeZoneForm(request.POST)
            if tz_form.is_valid():
                timezone.activate(tz_form.cleaned_data['event_time_zone'])
        return super(EventAdmin, self).add_view(request, form_url, extra_context)



在管理员编辑视图中正确处理时区



Handling correctly timezones in the Admin edit view

class EventAdmin(admin.ModelAdmin):
    # ...

    # Override change view so we can peek at the timezone they've entered and
    # set the current time zone accordingly before the form is processed
    def change_view(self, request, object_id, form_url='', extra_context=None):
        if request.method == 'POST':
            tz_form = TimeZoneForm(request.POST)
            if tz_form.is_valid():
                timezone.activate(tz_form.cleaned_data['event_time_zone'])
        else:
            obj = self.get_object(request, unquote(object_id))
            timezone.activate(obj.event_time_zone)
        return super(EventAdmin, self).change_view(request, object_id, form_url, extra_context)

这篇关于Django基于每个对象时区保存datetime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆