2009-09-21 46 views
7

我試圖找到一種簡單的方法來構建顯示澳大利亞格式日期(dd/mm/yyyy)的窗體。這是我能找到的唯一方法。似乎應該有更好的解決方案。製作Django forms.DateField顯示使用當地日期格式

注意事項:

  • 創建一個新的部件,其在DD/MM/YYYY格式呈現日期值
  • 創建新日期字段預先設置查找日期格式字符串值列表嘗試使用

我想象中的理想的解決方案將自動定位將DateField但沒有爲我工作(的strftime似乎並沒有是Unicode友好的,但我沒有嘗試很辛苦)

我錯過了什麼嗎?有沒有更優雅的解決方案?這是一個穩健的方法嗎?

from models import * 
from django import forms 
import datetime 

class MyDateWidget(forms.TextInput): 

    def render(self, name, value, attrs=None): 

      if isinstance(value, datetime.date): 
        value=value.strftime("%d/%m/%Y") 

      return super(MyDateWidget, self).render(name, value, attrs) 


class MyDateField(forms.DateField): 

    widget = MyDateWidget 

    def __init__(self, *args, **kwargs): 
      super(MyDateField, self).__init__(*args, **kwargs) 
      self.input_formats = ("%d/%m/%Y",)+(self.input_formats) 


class ExampleForm(ModelForm): 
    class Meta: 
      model=MyModel 
      fields=('name', 'date_of_birth') 

    date_of_birth = MyDateField() 
+2

一個簡單的選擇是依靠javascript日曆小部件來執行本地化。我們使用的一個只是隱藏我的日期字段,並使用指定的本地格式創建另一個日期字段。 – olivergeorge 2009-09-28 22:19:55

+0

關於特定小部件和掛鉤小部件的任何信息? – dfrankow 2009-11-01 16:15:01

+0

我想我應該參考stackoverflow問題:http://stackoverflow.com/questions/114068/best-javascript-calendar-control。 – dfrankow 2009-11-01 16:16:47

回答

10

當然,我不是一個Django/Python的絕地,但...

我不認爲有什麼不對你的方法。這是一個乾淨的閱讀。

您可能不需要創建自己的小部件,只需在第一個窗體顯示中以適當的格式顯示日期即可。只需使用DateInput小部件的format參數,您應該可以。因此,在您MyDateField類我只想做:

class MyDateField(forms.DateField): 

    widget = forms.DateInput(format="%d/%m/%Y") 

    def __init__(self, *args, **kwargs): 
     super(MyDateField, self).__init__(*args, **kwargs) 
     self.input_formats = ("%d/%m/%Y",)+(self.input_formats) 

你可以使用formfield_callback(見accepted answer這個遠親的問題),這意味着:

def customize_fields(f): 
    if isinstance(f, DateTimeField): 
     datetime_field=forms.DateTimeField(widget= 
      forms.DateInput(format='%d/%m/%Y %h:%i')) 
     date_field.input_formats = ("%d/%m/%Y %h:%i",)+ 
      (date_field.input_formats) 
     return datetime_field 
    elif isinstance(f, DateField): 
     date_field=forms.DateField(widget= 
      forms.DateInput(format='%d/%m/%Y')) 
     date_field.input_formats = ("%d/%m/%Y",)+ 
      (date_field.input_formats) 
     return date_field 
    else: 
     return f.formfield() 

class MyModelForm(forms.ModelForm): 
    formfield_callback = customize_fields 

    class Meta: 
     model = ... 

這樣完全省去了您MyDateField但可能會引入 - 如果您希望每個表單類都可以調用customize_fields - 需要ModelForm後代,請將formfield_callback=customize_fields作爲所有表單類的新基礎。

我與使用formfield_callback機制問題是雙重的:

  1. 這是不太可讀並依賴於ModelForms的內部工作的知識。我找不到任何地方formfield_callback實際文檔...

  2. 如果你需要重新定義中的ModelForm示範場,說做不需要形式的特定實例的領域,像這樣:

    class MyModelForm(forms.ModelForm): 
         formfield_callback = customize_fields 
         foo = forms.DateField(required=false) 
    
         class Meta: 
          model = Bar 
    

    您正在覆蓋由customize_fields返回的表單字段,因此完全失去了自定義。

我覺得你的方法更具可讀性。

+0

另外,請看看這個: http://code.djangoproject.com/ticket/7980 – cethegeek 2009-10-16 00:53:23

6

我以前使用過這種簡單的方法:只需設置DateField的'format'屬性即可。小部件在窗體的初始化:

class ExampleForm(ModelForm): 

     class Meta: 
      model = MyModel 

     def __init__(self, *args, **kwargs): 
      super(ModelForm, self).__init__(*args, **kwargs) 
      self.fields['date_of_birth'].widget.format = '%d/%m/%Y' 

      # at the same time, set the input format on the date field like you want it: 
      self.fields['date_of_birth'].input_formats = ['%d/%m/%Y'] 
0

在我的形式I'me使用:

def today(): 
    from datetime import date 
    return date.today().strftime("%d.%m.%Y") 

when = models.DateField(u'Когда', default=today) 
2

所有的自定義部件的東西可被繞過。

下面是摘錄自django/forms/widgets.py

class DateInput(TextInput): 
    def __init__(self, attrs=None, format=None): 
     super(DateInput, self).__init__(attrs) 
     if format: 
      self.format = format 
      self.manual_format = True 
     else: 
      self.format = formats.get_format('DATE_INPUT_FORMATS')[0] 
      self.manual_format = False 

你會發現,小部件的格式使用格式模塊設置。格式模塊根據語言環境進行選擇。如果您從美國瀏覽,Django默認會選擇django.conf.formats.locale.en.formats.py。在這裏你可以找到默認格式:

DATE_INPUT_FORMATS = (
    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06' 
    # '%b %d %Y', '%b %d, %Y',   # 'Oct 25 2006', 'Oct 25, 2006' 
    # '%d %b %Y', '%d %b, %Y',   # '25 Oct 2006', '25 Oct, 2006' 
    # '%B %d %Y', '%B %d, %Y',   # 'October 25 2006', 'October 25, 2006' 
    # '%d %B %Y', '%d %B, %Y',   # '25 October 2006', '25 October, 2006' 
) 

正如你在第一個代碼塊中看到的,Django選擇其中的第一個。徹底改變格式的方法是創建你自己的格式模塊,重寫Django的缺省語言環境。爲此,請查看FORMAT_MODULE_PATH。如果你所要做的只是覆蓋默認的日期格式,我說節省一些時間和猴子補丁。我將它添加到了我的設置文件中,並且我的首選默認格式一切都看起來很出色:

DATE_INPUT_FORMATS = ('%m/%d/%Y', '%m/%d/%y', '%Y-%m-%d', 
         '%b %d %Y', '%b %d, %Y', '%d %b %Y', 
         '%d %b, %Y', '%B %d %Y', '%B %d, %Y', 
         '%d %B %Y', '%d %B, %Y') 
from django.conf.locale.en import formats 
formats.DATE_INPUT_FORMATS = DATE_INPUT_FORMATS