2009-09-21 6 views
7

オーストラリアの形式(dd/mm/yyyy)で日付を表示するフォームを簡単に作成しようとしています。これが私がそれをするために見つけることができる唯一の方法でした。よりよい解決策があるはずです。注意すべきDjangoフォームを作成する.DateField showローカル日付形式を使用する

物事:それはしようとする値のリストに見つけ日付書式文字列を付加するために、新しい日付フィールドを作成し

  • DD/MM/yyyyの形式で日付値をレンダリングする新しいウィジェットを作成し

    を使用するために、私は理想的なソリューションは、自動的にローカライズされたが、それが私のために動作しませんでしたDateFieldのだろうと想像

    012(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

    1つの簡単な方法は、ローカライゼーションを行うためにJavaScriptのカレンダーウィジェットを使用することです。私たちが使用するのは、単に日付フィールドを隠し、ローカルフォーマットを指定して別のフィールドを作成するだけです。 – olivergeorge

    +0

    特定のウィジェットに関する情報とウィジェットの接続 – dfrankow

    +0

    私はstackoverflowの質問を参照する必要があります:http://stackoverflow.com/questions/114068/best-javascript-calendar-control。 – dfrankow

    答えて

    10

    、私はあなたのアプローチに何か問題があるとは思わないジャンゴ/ Pythonのジェダイないんだけど、...

    。それはきれいな読書です。

    最初のフォーム表示に適切な形式で日付を表示するために、独自のウィジェットを作成する必要はありません。 DateInputウィジェットにformatパラメータを使用するだけでOKです。だからあなたの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の必要性を排除することを行いますすべてのフォームクラスの新しいベースとしてformfield_callback=customize_fieldsを実装すると、すべてのフォームクラスがcustomize_fieldsを呼び出すようにしたい場合は、ModelFormの子孫が必要です。

    formfield_callbackメカニズムを使用して私の問題は二つある:

    1. それはあまり読みやすいとModelFormsの内部の仕組みの知識に依存しています。 formfield_callbackについての実際のドキュメントはどこにも見つかりません...

      など、フォームの特定のインスタンスにフィールドを必要としないようにするには、ModelFormでモデルフィールドを再定義する必要がある場合は、
      class MyModelForm(forms.ModelForm): 
           formfield_callback = customize_fields 
           foo = forms.DateField(required=false) 
      
           class Meta: 
            model = Bar 
      

      custom_fieldsから返されたフォームフィールドを上書きしているため、カスタマイズが完全に失われています。

    私はあなたのアプローチがより読みやすいと思います。

    +0

    また、これを見てください: http://code.djangoproject.com/ticket/7980 – cethegeek

    6

    私はこの単純なアプローチを使いました。これは、DateFieldの 'format'属性を設定するだけです。フォームの初期化でウィジェット:使用I'me私の形で

    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

    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