This question already has an answer here:
Why form is not valid in django
(1 answer)
Closed 8 months ago.
In my views.py my have a view where a user can create a post with a title, media file and caption.
When i check if form.is_valid(): it always returns as false and i cannot see the issue with my form.
views.py
def your_profile(request):
if request.method == "POST":
form = CreatePost(request.POST)
if form.is_valid():
title = form.cleaned_data.get("title_input")
media = form.cleaned_data.get("media_input")
caption = form.cleaned_data.get("caption_input")
context = {"title": "Your Profile"}
return render(request, "myApp/your_profile.html", context)
forms.py
class CreatePost(forms.Form):
title = forms.CharField(max_length=30)
media = forms.FileField(max_length=350)
caption =forms.CharField(max_length=300)
html
<form action="" method="post">
<input type="text" name="title_input" id="title_input">
<label for="title_input">Title</label>
<input type="file" name="media_input" id="media_input">
<label for="media_input">Media</label>
<input type="text" name="caption_input" id="caption_input">
<label for="caption_input">Caption</label>
<input type="submit" value="POST!">
</form>
Just ad the else block, like here:
if form.is_valid():
...
else:
print(form.errors)
It will output the <li></li> tag with the name of the field and the error.
You also forgot to add:
{% csrf_token %}
Inside of your <form></form> tag in the .html
Also the name attributes of <input> tags must be similar with the names of the fields in the model.
This always works for me.
Remove the "_input" from the "name" tag in HTML. The form is not able to find the field values. The name tag should have the same value as the corresponding attribute of the Form class.
Related
I have a Django form with a check box for "Accept terms of service" but if I check it or not my app blocks the request with the message "you have to accept our Terms of service".
Here is my code:
forms.py
class ProfileModelForm(ModelForm):
class Meta:
model = UserProfile
fields = ['u_fullname',
'u_job',
'u_country',
'u_email',
'u_terms',
]
def clean(self):
cleaned_data = super(ProfileModelForm, self).clean()
u_fullname = cleaned_data.get('u_fullname')
u_job = cleaned_data.get('u_job')
u_country = cleaned_data.get('u_country')
u_email = cleaned_data.get('u_email')
u_terms = cleaned_data.get('u_terms')
if not u_terms:
raise forms.ValidationError("Please read and accept our Terms of Service")
if not u_fullname and not u_job and not u_country and not u_terms:
raise forms.ValidationError('You have to write something!')
return cleaned_data
Field u_terms is a Booleanfield in my model.
the views.py:
if request.method == 'POST':
if 'user_reg' in request.POST:
form = ProfileModelForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
#Create user and get the id
n_user = User.objects.create_user(username=request.POST['u_email'],
email=request.POST['u_email'],
password=request.POST['u_password'])
instance.user = User.objects.get(id=n_user.id)
instance.u_profile = 'U'
print("TERMS-->",request.POST['u_terms'])
instance.save()
return # Put return here
else:
messages.error(request, "Error")
#form = ProfileModelForm()
return render(request, 'login.html', {'form': form})
elif 'register' in request.POST:
pass
elif 'company' in request.POST:
pass
and the html template part related to my checkbox:
<div class="col-lg-12 no-pdd">
<div class="checky-sec st2">
<div class="fgt-sec">
<input type="checkbox" name="cc" id="c2" value={{ form.u_terms }}>
<label for="c2">
<span></span>
</label>
<small>Yes, I understand and agree to the workwise Terms & Conditions.</small>
</div><!--fgt-sec end-->
</div>
</div>
I imagine the problem is in my html part but I don't know how can I manage boolean fields from checkbox.
Someone can help me?
The "name" attribute of your <input> element does not match the POST attribute expected by your form: cc != u_terms.
You can solve this in two ways:
Use {{ form.u_terms }} to render the entire <input> tag. Note that you put that into the value attribute, which is wrong (look at the source code inside your browser, you'll see what I mean).
{{ form.u_terms }}
{{ form.u_terms.label_tag }}
If you must customise attributes of your <input> (which doesn't seem to be the case here), then make sure you still refer to your form's field so that the various attributes are correct:
<input type="checkbox" name="{{ form.u_terms.html_name }}" id="{{ form.u_terms.id_for_label }}" class="some-custom-class">
<label for="{{ form.u_terms.id_for_label }}"><span></span></label>
I've got a problem with django with handling forms : I created a form with 2 fields, and I associated it to my view, but it tells me that my fields are undefined. Could you explain me please ?
I created a form in my index.html :
<form action="/addUser" method="post">
{% csrf_token %}
<label> Name of the Employee : <input type="text" name="employeeName", id="employeeName"/> </label>
<label> Email of the Employee : <input type="email" name="employeeEmail", id="employeeEmail" /> </label>
<button class="btn btn-primary" type="submit">Add User</button>
</form>
Then I created in views.py
def addUser(request):
if request.method == 'POST':
form = CreationUserForm(request.POST)
newEmployee = Employee()
newEmployee.name = form[employeeName]
newEmployee.email = form[employeeEmail]
newEmployee.save()
return HttpResponseRedirect(reverse('app:home'))
And then I created in forms.py
class CreationUserForm(forms.Form):
employeeName = forms.CharField(label='employeeName', max_length=254)
employeeEmail = forms.CharField(label='employeeEmail', max_length=254)
So I don't understand why I get this error : name 'employeeName' is not defined
For my point of view it is...
I tried with form.employeeName too, but it considered as a non existant attribute.
Thank you for helping :)
In your addUser method, both the employeeName and employeeEmail are variables, which are not defined. You want to be accessing the keys via the strings.
def addUser(request):
if request.method == 'POST':
form = CreationUserForm(request.POST)
newEmployee = Employee()
newEmployee.name = form['employeeName']
newEmployee.email = form['employeeEmail']
newEmployee.save()
return HttpResponseRedirect(reverse('app:home'))
also a Django suggestion - before accessing the attributes of the form, it is often useful to check that the input is valid by calling if form.is_valid() as defined here: https://docs.djangoproject.com/en/2.2/ref/forms/api/
I have created a form with select field in template ehrinfo.html
<form action="{% url 'ehrs:compcreate' %}" method="GET">
<select>
<option value="Vital Signs">Vital Signs</option>
<option value="Cancer Signs">Cancer Signs</option>
</select><br><br>
<input type="submit" value="Select Template" class="addehr">
</form>
I have defined form class as:
class templateselect(forms.Form):
CHOICES = (
('Vital Signs', 'Vital Signs'),
('Cancer Signs', 'Cancer Signs'),
)
template = forms.ChoiceField(widget=forms.Select, choices=CHOICES)
Now I want to get selected text from this form in view compcreate. So I used:
def compcreate(request):
if request.method == 'GET':
form = templateselect(request.GET)
print("a")
if form.is_valid():
print("b")
template = str(form.cleaned_data["template"])
but it cant get past the if form.is_valid(): part as 'a' is printed but 'b' is not printed on console. What is the problem? How can I get the selected text in compcreate()?
The proper way to render your form would be to pass it in to your template via the context object and change your template. For example:
<form action="{% url 'ehrs:compcreate' %}" method="GET">
{{ form.as_p }}<br><br>
<input type="submit" value="Select Template" class="addehr">
</form>
If you want to stick with your current setup, looking at the html produced by the previous solution suggests that adding a name (equal to the name of your field in the Form class declaration) to your select field should also work:
<form action="{% url 'ehrs:compcreate' %}" method="GET">
<select name="template">
<option value="Vital Signs">Vital Signs</option>
<option value="Cancer Signs">Cancer Signs</option>
</select><br><br>
<input type="submit" value="Select Template" class="addehr">
This approach works with ModelForm and POST request:
def compcreate(request):
if request.method == 'POST':
form = templateselect(request.POST)
if form.is_valid():
ts = form.save(commit=False)
print(ts.template)
Let me know if it works in your case.
I want to update database values by HTML Forms
HTML form :
<form action="/school_manager/students/{{student.id}}/update/" method="post" accept-charset="utf-8">
{% csrf_token %}
<label for="update_name">Edit Name :</label><br/>
<input type="text" name="update_name" id="update_name" placeholder="Enter A Name" />
<input type="submit" value="Update"/>
</form>
views.py :
def update_student_detail(request, student_id):
list = get_object_or_404 ( student, pk=student_id)
if request.method == 'POST' :
student.First_Name = request.POST.get('update_name','')
list.save()
return HttpResponseRedirect('/school_manager/students/' + student_id)
When I run the program and type a word in text box, after submit it does not work. I can't see any change to my database.
I found my fault
in views.py calling student for change database values is wrong
When we created a list of database tuple, values can edit by using that list
def update_student_detail(request, student_id):
list = get_object_or_404 ( student, pk=student_id)
if request.method == 'POST' :
list.First_Name = request.POST.get('update_name','')
list.save()
return HttpResponseRedirect('/school_manager/students/' + student_id)
i have an custom form , whenever i fetch the form values to save in the database than it display an error ( applicationform() got an unexpected keyword argument 'job_title' ) and the values are not save in the table.
views.py :-
def applicationvalue(request):
if request.method == 'POST':
getjobtitle = request.POST['jobtitle']
getintable = applicationform(job_title=getjobtitle)
getintable.save()
print getjobtitle
return HttpResponse(getintable)
else:
return render_to_response('registration/applicationform.html')
my form is :-
<form method="POST" action="#" class="form-horizontal" id="applicationform" name="appform">
<input type="text" id="u_jobtitle" class="input-xlarge" name="jobtitle" value=" " />
<button class="btn btn-gebo" type="submit" name="usubmit">Save changes</button>
whenever i fetch the values from form to save the values in table field " job_title " than it will display an error :-
applicationform() got an unexpected keyword argument 'job_title'
Change input field name to job_title in your html
<input name="job_title" type="text" id="u_jobtitle" class="input-xlarge" value=" " />
-------------^ changed
and then in view do
def applicationvalue(request):
if request.method == 'POST':
#Dont need this
#getjobtitle = request.POST['jobtitle']
#---------------------------Use request.POST
getintable = applicationform(request.POST)
getintable.save()
print getjobtitle
return HttpResponse(getintable)
else:
return render_to_response('registration/applicationform.html')
It will be better if you use same form to render html instead of hand coding it.
The applicationform constructor should take the request.POST as argument.
But it seems to me that you are not using django forms in the "right" way. I think that your view doesn't follow the django philosophy for using form.
In your case, you should have a model:
from django.db import models
class Application(models.Model):
job_title = models.CharField(max_length=100)
Based on this model, you can declare a ModelForm:
from django import forms
from .models import ApplicationModel
class ApplicationForm(forms.ModelForm):
class Meta:
model = ApplicationModel
fields = ('job_title',)
Then you can use this form in your view
def applicationvalue(request):
if request.method == 'POST':
form = ApplicationForm(request.POST)
if form.is_valid():
#This is called when the form fields are ok and we can create the object
application_object = form.save()
return HttpResponse("Some HTML code") # or HttResponseRedirect("/any_url")
else:
form = ApplicationForm()
#This called when we need to display the form: get or error in form fields
return render_to_response('registration/applicationform.html', {'form': form})
finally you should have a registration/applicationform.html template with something like:
{% extends "base.html" %}
{% block content %}
<form action="" method="post">{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" value="Add">
</form>
{% endblock %}
I hope it helps