Django models\uuuuUnicode\uuuu:如何返回包含本地化日期时间的值?

Django models\uuuuUnicode\uuuu:如何返回包含本地化日期时间的值?,django,datetime,django-models,timezone,django-i18n,Django,Datetime,Django Models,Timezone,Django I18n,我有一个本地化的Django应用程序,本地化工作良好,配置正常 对于表单需求,我使用model的\uuuuu unicode\uuu方法来呈现modelschoicefields,但是如何在unicode返回中设置本地化日期的格式 在这种方法中,我无法访问当前时区,如何向我的用户正确显示我的TimeSpanList?目前,它显示UTC。我尝试了django.template.defaultfilters.date和Simon Charette的django.utils.formats.local

我有一个本地化的Django应用程序,本地化工作良好,配置正常

对于表单需求,我使用model的
\uuuuu unicode\uuu
方法来呈现modelschoicefields,但是如何在unicode返回中设置本地化日期的格式

在这种方法中,我无法访问当前时区,如何向我的用户正确显示我的TimeSpanList?目前,它显示UTC。我尝试了
django.template.defaultfilters.date
和Simon Charette的
django.utils.formats.localize
,但没有帮助,因为它们可能缺少上下文数据

class TimeSpan(models.Model):
    start = models.DateTimeField(_("start"))
    end = models.DateTimeField(_("end"))

    def __unicode__(self):
        return u"from UTC:{0} to UTC:{1}".format(self.start, self.end)

class TimeSpanChooserForm(forms.Form):
    time_span = forms.ModelChoiceField(
        label=_("time span"), queryset=TimeSpan.objects.all())

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request", None)
        super(TimeSpanChooserForm, self).__init__(*args, **kwargs)
如何知道当前语言环境而不使用当前请求对象来本地化这些日期时间?(如果有办法的话)

注意:对我来说,
\uuuuuunicode\uuuuu
似乎是在ModelChoiceField中显示条目的唯一方法


注2:对我来说,Yuji'Tomita'Tomita注释是目前最好的答案,但它缺少一个可用的示例…

您可以使用
django.utils.formats.localize
函数

from django.db import models
from django.utils.formats import localize
from django.utils.translation import ugettext

class TimeSpan(models.Model):
    start = models.DateTimeField(_('start'))
    end = models.DateTimeField(_('end'))

    def __unicode__(self):
        return ugettext("from %(start)s to %(end)s") % {
            'start': localize(self.start),
            'end': localize(self.end),
        }
您可以使用这些操作测试以下工作

from django.utils import timezone
from django.utils.translation import override

with override('fr'):
    print(TimeSpan(start=timezone.now(), end=timezone.now()))

with override('en'):
    print(TimeSpan(start=timezone.now(), end=timezone.now()))
两者都应显示不同的格式

如果要确保日期显示在特定的时区中,则必须确保在设置中使用
USE_TZ=True
,并将
时区设置设置为要使用的时区。您可以使用中间件来为每个请求设置此时区,该中间件使用所需的时区调用
django.utils.timezone.activate

您也可以使用为您提供此功能的软件包。

尝试以下操作:

def __unicode__(self):
    return u'%s %s'%(self.start,self.end)

使用此购买它将返回组合的开始和结束日期时间对象。这对我很有效

感谢您提醒我这个问题。要得到一个完整的答案有点复杂

我已经创建了一个演示方法来演示这一点。运行
test()
查看输出

剩下的挑战是获取客户端时区。这可能需要使用一些JavaScript来完成,这些JavaScript向GET/POST添加了一个参数,或者添加了一个要在视图中读取的自定义头

因为这是未知的,所以我用一个返回随机时区的方法将其删除。您应该更新它以反映您的客户端时区检索方法

下面是一个自我记录的示例:

模型 形式 看法
你不能。不要在模板中使用unicode方法,直接访问日期。但是对于由表单处理的选择字段,您该怎么做?您可以始终将请求传递给表单。您不应该考虑严格修改
\uuuuuuunicode\uuuuu
来确定默认情况下在选择字段中填充的内容。这些是方便的自动默认值。除此之外,我会直接修改表单。转换到客户机语言环境对于视图和请求来说似乎是非常局部的。否则,这些时间跨度的管理员表示将默认为您自己的管理员TZ。查看动态修改选项字段选项!我添加了一个表单库,这样您就可以在一个我可以接受的完整答案中完成它。您将如何从这里更改带有本地化日期的渲染?本地化功能现在如何成为良好的语言环境?我刚刚尝试过,它仍然返回UTC datetime…如果您想让Django考虑浏览器的区域设置首选项,您必须确保
LocaleMiddleware
MIDDLEWARE\u CLASSES
设置中,
USE\u I18N
USE\u L10N
设置都设置为
True
,并且在
语言设置中有要支持的语言项。我的设置正常,所有日期都由django模板或日期时间字段(django表单)显示很好…我的问题是关于这些日期时间的本地化…我想答案更复杂,我从你的建议开始,但它显示UTC日期时间而不是本地化的数字…哈,这当然是我等待的答案,谢谢。
from django.utils.formats import localize


class TimeSpan(models.Model):
    start = models.DateTimeField("start")
    end = models.DateTimeField("end")

    def __unicode__(self):
        return u"from UTC:{0} to UTC:{1}".format(self.start, self.end)
from django import forms

class TimeSpanChooserForm(forms.Form):
    time_span = forms.ModelChoiceField(
        label=("time span"), queryset=TimeSpan.objects.all())

    def __init__(self, *args, **kwargs):
        # get request and TZ from view. This is a special form..
        self.request = kwargs.pop("request", None)
        self.tz = kwargs.pop('tz', None)
        super(TimeSpanChooserForm, self).__init__(*args, **kwargs)

        # modify the choices attribute to add custom labels.
        self.fields['time_span'].choices = [
            self.make_tz_aware_choice(self.request, timespan) for timespan in self.fields['time_span'].queryset
        ]

    def make_tz_aware_choice(self, request, timespan):
        """ Generate a TZ aware choice tuple.
        Must return (value, label). In the case of a ModelChoiceField, (instance id, label).
        """
        start = timespan.start.replace(tzinfo=self.tz)
        end = timespan.end.replace(tzinfo=self.tz)
        label = "From {tz} {start} to: {tz} {end}".format(
            start=start,
            end=end,
            tz=self.tz,
        )
        return (timespan.id, label)
import random
import pytz

from django import http
from django import template

def view(request):
    """ Render a form with overridden choices respecting TZ
    """
    def get_tz_from_request(request):
        """ Get the client timezone from request.
        How you do this is up to you. Likely from JS passed as a parmeter.
        """
        random_timezone = random.choice(pytz.all_timezones)
        return pytz.timezone(random_timezone)

    form = TimeSpanChooserForm(request.POST or None, request=request, tz=get_tz_from_request(request))
    ctx = template.Context({
        'form': form,
    })
    rendered_template = template.Template("{{ form }}").render(ctx)
    return http.HttpResponse(rendered_template)


def test():
    from django.test import RequestFactory

    rf = RequestFactory()
    r = rf.get('/')

    for i in range(10):
        print str(view(r))