Reputation: 3
I've been trying to figure out why form.is_valid always return false but I still haven't figured it out yet and it doesn't help that I've just started with Django.
Model
class Post(models.Model):
STATUS_CHOICES = (
('d', 'Draft'),
('p', 'Published'),
)
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=120, null=True, blank=True)
text = models.TextField(max_length=500, null=True, blank=True)
slug = models.SlugField(max_length=40, unique=True)
publish_date = models.DateTimeField(null=True)
status = models.CharField(choices=STATUS_CHOICES, max_length=1,default='d')
Form
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title','author','slug','text','publish_date','status')
widgets = {
'title': forms.TextInput(attrs={'class' : 'form-control', 'placeholder' : 'Title'}),
'author': forms.Select(),
'slug': forms.TextInput(attrs={'class' : 'form-control', 'placeholder' : 'Slug'}),
'text': forms.Textarea(attrs={'class' : 'form-control', 'placeholder' : 'Text'}),
'publish_date': forms.DateInput(attrs={'class' : 'form-control', 'placeholder' : date.today}),
'status': forms.NullBooleanSelect(attrs={'class' : 'form-control'}),
}
View
def admin(request):
if request.user.is_authenticated:
if request.user.is_staff:
users = User.objects.all().order_by('date_joined').reverse()[:5]
posts = Post.objects.all().order_by('created').reverse()[:5]
publications = Publication.objects.all().order_by('created').reverse()[:5]
form = PostForm()
args = {'profile' : users ,'posts' : posts, 'publications' : publications, 'form' : form }
if request.POST:
print('request is posting')
if form.is_valid():
form.save()
else:
print('Error in saving')
return render(request, 'webadmin/index.html',args)
else:
return index(request)
else:
return redirect('/webmaster/login/')
I do hope that you can help me, Thank you OWO)/
Upvotes: 0
Views: 752
Reputation: 77942
Here:
form = PostForm()
if request.POST:
if form.is_valid():
you're trying to validate an unbound form, which is garanteed to fail - you have to pass data (in this case request.POST
) to have something to validate. Your code should actually looks something like:
# explicitely test against request.method -
# you can have a POST request with an empty body,
# in which case `request.POST` will be empty and
# have a false value in a boolean test
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
# ...
Now even passing request.POST
doesn't mean your form will necessarily validate, but just printing something like "'Error in saving'" will not tell you what's wrong or missing.
An invalid form has an .errors
attributes that lists all the validation errors. Those validation errors are automatically displayed in your template if you use {{ form }}
(or it's variants {{ form.as_p }}
, {{ form.as_table }}
etc to render the form in your template (which you did not post here). If you're rendering the form manually, you have to think of rendering the errors by yourself as well as documented here (I do hope you're at least using the form's fields for rendering instead of writing all the html form code manually...).
In all cases you can at least start with printing out form.errors
in your view, so you have a clue about what doesn't validate, ie:
if form.is_valid():
form.save()
else:
print("errors : {}".format(form.errors))
Note that all of this is clearly documented, so you could have found the answers by yourself. I understand that Django is a rather large framework and that it can takes time to master it, but it has a rather good tutorial and extensive documentation with lot of examples, so you should really do the tutorial and start browsing the doc, at least to have an idea of what you can find in and where to search when something "doesn't work".
Upvotes: 1