带有HiddenInput的Django的ModelForm返回无效

时间:2010-12-19 21:13:01

标签: python django django-forms

我正在制作一个小项目来学习Django,我在尝试在ModelForm中使用隐藏字段时遇到了一些问题。

Theres the class:

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。 我做错了什么?

3 个答案:

答案 0 :(得分:2)

您希望发布日期是发布日期吗? 您是否在模型中尝试过auto_now?

pub_date    = models.DateTimeField(auto_now=True)

答案 1 :(得分:1)

问题在于从字符串到datetime对象的转换。

如果未指定input_formats参数,则datetime字段采用这些格式进行string-&gt; 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的默认窗口小部件是DateTimeInput窗口小部件,可以正确地将datetime格式化为字符串,但HiddenInput只需要使用没有格式化的日期时间对象'显示了。

如果您想使用HiddenInput,则需要strftime datetime对象的格式正确。

如果您只想隐藏它,另一个选择是不将窗口小部件设置为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;'}),
        }

答案 2 :(得分:0)

另一种方法是将窗口小部件类型更改为SplitHiddenDateTimeWidget