Reputation: 2069
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?
Upvotes: 4
Views: 3267
Reputation: 6594
Another alternative is to just change the widget type to SplitHiddenDateTimeWidget
Upvotes: 1
Reputation: 118498
The problem is in the conversion from string to datetime object.
The datetime field, if no input_formats
argument is specified, takes these formats for string->datetime conversion.
(from the docs: 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'
So your value of 2010-12-19 17:08:22.498000
won't work.
The default widget for DateTimeField
is DateTimeInput
widget which formats the datetime
to a string correctly, but HiddenInput
just takes the datetime object w/ no formatting as you've shown.
If you want to use HiddenInput
you need to strftime
the datetime
object 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 DateTimeInput
widget as is and hide that element with the attrs
argument.
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;'}),
}
Upvotes: 1
Reputation: 1551
Do you want the pub date to be the date of the post? Is so have you tried auto_now in your models?
pub_date = models.DateTimeField(auto_now=True)
Upvotes: 2