I’m making a small project to learn Django, and i’m having some problems trying to use hidden fields inside a ModelForm.
Theres the class:
class Post(models.Model):
title = models.CharField(max_length = 140)
message = models.CharField(max_length = 10000)
pub_date = models.DateTimeField()
And my ModelForm:
class PostForm(ModelForm):
class Meta:
model = Post
fields = ('title', 'message', 'pub_date',)
widgets = {
'message' : Textarea(attrs={'cols':80, 'rows':20}),
'pub_date' : HiddenInput(),
}
This is the view:
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))
This is the HTML generated for the form:
<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>
I use the same template to both create and edit posts. When i’m creating, pub_date is set in another view, and when i’m editing, I can’t change pub_date on my template (thus the hidden field).
On this example, form.is_valid() always return False.
If I remove the 'pub_date' : HiddenInput(), line from my form, it returns True.
What am I doing wrong?
The problem is in the conversion from string to datetime object.
The datetime field, if no
input_formatsargument is specified, takes these formats for string->datetime conversion.(from the docs: http://docs.djangoproject.com/en/dev/ref/forms/fields/#datetimefield)
So your value of
2010-12-19 17:08:22.498000won’t work.The default widget for
DateTimeFieldisDateTimeInputwidget which formats thedatetimeto a string correctly, butHiddenInputjust takes the datetime object w/ no formatting as you’ve shown.If you want to use
HiddenInputyou need tostrftimethedatetimeobject to be in the correct format.An alternative option if you just want to hide it is to not set the widget as HiddenInput but simply keep the
DateTimeInputwidget as is and hide that element with theattrsargument.