2015-03-27 6 views
2

У меня есть локализованная Django App, локализация работает хорошо и конфигурация нормально ...Модели Django __unicode__: Как вернуть значение, содержащее локализованные даты?

Для форм потребности, я использую __unicode__ метод модель для визуализации ModelChoiceFields, но как форматировать локализована дата в обратном юникоде?

В этом методе у меня нет доступа к текущему часовому поясу, как правильно отображать мой TimeSpanList для моих пользователей? В настоящее время отображается UTC. Я судимое django.template.defaultfilters.date и Симон 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) 

Как узнать текущую локаль без текущего объекта запроса, чтобы локализовать это DateTimes? (Если есть способ)

примечание: мне __unicode__ кажется единственным способом отображения записей в ModelChoiceField.

примечание 2: мне, Юдзи «Томиты» Томита комментарий лучший текущий ответ, но ему не хватает полезной Exemple ...

+0

Вы не можете. Не используйте метод unicode в шаблоне, напрямую обращайтесь к датам. –

+0

Но для поля выбора, обрабатываемого формой, как вы это делаете? – christophe31

+0

Вы всегда можете отправить запрос в форму. – Brandon

ответ

4

Спасибо за напоминание об этом вопросе. Это немного связано с полным ответом.

Я создал демонстрационный метод, который показывает это в действии. Запустите test(), чтобы увидеть выход.

Остальная задача - получить часовой пояс клиента. Это, вероятно, будет сделано с помощью некоторого JavaScript, который добавляет параметр в ваш GET/POST или добавляет настраиваемый заголовок для чтения в представлении.

Поскольку это неизвестно, я просто отключил его методом, который возвращает случайный часовой пояс. Вы должны обновить его, чтобы отразить метод поиска часовых поясов вашего клиента.

Вот документирован пример:

Модели
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)) 
+0

Хаа, это, безусловно, ответ, которого я ждал, спасибо. – christophe31

+0

@ christophe31 без проблем. спасибо за интернет-очки! –

0

Вы можете использовать функцию 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 в ваших настройках и установите для параметра TIME_ZONE значение, которое вы хотите использовать. Вы можете установить этот часовой пояс для каждого запроса, используя промежуточное программное обеспечение, которое вызывает django.utils.timezone.activate с нужным часовым поясом.

Вы также можете воспользоваться пакетом django-sundial, который позаботится об этом для вас.

+0

Как локализовать fonction теперь хороший язык? Я просто попробовал, он по-прежнему возвращает UTC datetime ... – christophe31

+0

Если вы хотите, чтобы Django учитывал предпочтение локали браузера, вы должны убедиться, что 'LocaleMiddleware' находится в настройке' MIDDLEWWARE_CLASSES', что установлены как USE_I18N, так и 'USE_L10N'. установите значение «Истина» и у вас есть записи для языка, который вы хотите поддерживать в настройке «ЯЗЫК». –

+0

мои настройки в порядке, все даты, отображаемые шаблоном django или в полях datetime (формы django), хороши ... – christophe31

-2

Попробуйте это:

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

Покупка с помощью этого он возвращает объединенные начала и окончания DateTime objects.This работал для меня

+0

Моя проблема заключается в локализации данных datetime ... Я полагаю, что ответ более сложный, я начал с того, что вы предлагаете, но отображает UTC datetime вместо локализованных чисел ... – christophe31

 Смежные вопросы

  • Нет связанных вопросов^_^