2010-12-19 25 views
2

Djangoを学ぶための小さなプロジェクトを作っています.ModelForm内の隠しフィールドを使用しようとするといくつかの問題があります。DjangoのHiddenInputを持つModelFormが無効を返す

クラスTheresの:

class Post(models.Model): 
    title  = models.CharField(max_length = 140) 
    message  = models.CharField(max_length = 10000) 
    pub_date = models.DateTimeField() 

そして、私のModelForm:

class PostForm(ModelForm): 
    class Meta: 
     model = Post 
     fields = ('title', 'message', 'pub_date',) 
     widgets = { 
      'message' : Textarea(attrs={'cols':80, 'rows':20}), 
      'pub_date' : HiddenInput(), 
     } 

これは図である。

def edit(request, post_id): 
    if request.method == 'POST': 
     form = PostForm(request.POST, request.FILES) 
     if form.is_valid(): 
      print 'VALID' 
      dados = form.cleaned_data 
      post = Post.objects.get(pk=post_id) 
      post.title = dados['title'] 
      post.message = dados['message'] 
      post.save() 
      return HttpResponseRedirect(reverse('blog.views.detail', args=(post.id,))) 
     else: 
      print 'INVALID' 
    form = PostForm(instance=Post.objects.get(pk=post_id)) 
    return render_to_response('blog/add_post.html', {'form' : form,}, context_instance = RequestContext(request)) 

これは、フォームのために生成されたHTMLです:

<div style='display:none'> 
<input type='hidden' name='csrfmiddlewaretoken' 
value='3b7c0735bf464fb4fd7dcd3011050e1c' /> 

</div> 
<tr> 
    <th><label for="id_title">title:</label></th> 
    <td><input id="id_title" type="text" name="title" value="asd1111111111" maxlength="140" /></td> 
</tr> 
<tr> 
    <th><label for="id_message">message:</label></th> 
    <td><textarea id="id_message" rows="20" cols="80" name="message">asd11111111111</textarea> 
    <input type="hidden" name="pub_date" value="2010-12-19 17:08:22.498000" id="id_pub_date" /></td> 
</tr> 

投稿の作成と編集に同じテンプレートを使用します。私が作成しているとき、pub_dateは別のビューで設定されています。私が編集しているときに、私のテンプレートのpub_dateを変更することはできません。 この例では、form.is_valid()は常にFalseを返します。 フォームから'pub_date' : HiddenInput(),行を削除すると、Trueが返されます。 私は何が間違っていますか?

+0

(隠しフィールドで)生成されたページのHTMLとは何ですか? – Robert

+0

Ops、質問に追加するのを忘れてしまった。完了しました。 –

+0

'form.errors'を印刷するとどうなりますか? – Robert

答えて

1

問題は文字列からdatetimeオブジェクトへの変換にあります。

input_formats引数が指定されていない場合、datetimeフィールドはstring-> datetime変換のためにこれらの形式をとります。 (ドキュメントから:http://docs.djangoproject.com/en/dev/ref/forms/fields/#datetimefield

'%Y-%m-%d %H:%M:%S',  # '2006-10-25 14:30:59' 
'%Y-%m-%d %H:%M',  # '2006-10-25 14:30' 
'%Y-%m-%d',    # '2006-10-25' 
'%m/%d/%Y %H:%M:%S',  # '10/25/2006 14:30:59' 
'%m/%d/%Y %H:%M',  # '10/25/2006 14:30' 
'%m/%d/%Y',    # '10/25/2006' 
'%m/%d/%y %H:%M:%S',  # '10/25/06 14:30:59' 
'%m/%d/%y %H:%M',  # '10/25/06 14:30' 
'%m/%d/%y',    # '10/25/06' 

だから2010-12-19 17:08:22.498000のあなたの価値は動作しません。 DateTimeFieldため

デフォルトのウィジェットが正しく文字列にdatetimeをフォーマットしていますが、示されてきたようにHiddenInputがちょうど書式なし/ wのDateTimeオブジェクトを受け取りDateTimeInputウィジェットです。

HiddenInputを使用する場合は、strftimedatetimeオブジェクトを正しい形式にする必要があります。

ウィジェットを非表示にしたい場合は、ウィジェットをHiddenInputとして設定するのではなく、DateTimeInputウィジェットをそのまま保ち、そのエレメントをattrs引数で非表示にします。

class PostForm(ModelForm): 
    class Meta: 
     model = Post 
     fields = ('title', 'message', 'pub_date',) 
     widgets = { 
      'message' : Textarea(attrs={'cols':80, 'rows':20}), 
      'pub_date' : DateTimeInput(attrs={'style': 'display:none;'}), 
     } 
+0

答えに感謝します。その場合、私はauto_nowとauto_now_addソリューションを使っています。 時間をフォーマットしたい場合、どこでそれを行うべきですか?フォームがすでに無効になっているという見解で私は傾けることができません。 –

+0

問題ありません!うーん、私はどのようにビューでそれを変更するか分からない。私はあなたの最善の策は、HiddenInputを使用していないとDateTimeInputは、フォーマットを処理させると思うが、ビューでそれを望む場合は、モデルインスタンスのpub_dateをmyinstance.pub_date.strftime( "%Y-%m-%d% H:%M:%S ")、それが動作するのか、フォームがDBに別の呼び出しを行ったのかはわかりません –

2

パブの日付を投稿の日付にしますか? あなたのモデルでauto_nowを試しましたか?

pub_date = models.DateTimeField(auto_now=True) 
+0

私はそれが可能であることを知らなかった、私はちょっとPythonとdjangoに新しいです。しかし、私はポストを更新するとこれは変わるだろうか? - それを忘れて、私はちょうどauto_now__addについて読む。 –

0

別の方法としては、ちょうどSplitHiddenDateTimeWidget

にウィジェットの種類を変更することです
関連する問題