I am new to programming, I hope my question is not very basic. Here I am trying to taking the input and showing output on the same page.
I went through an article that said I should use GET method to do so.
my view
def calc(request):
if request.method == 'GET':
form = CalculationForm(request.GET)
if form.is_valid():
number1 = form.cleaned_data.get('first_number')
number2 = form.cleaned_data.get('second_number')
sum = number1 + number2
sum.save()
return render(request, 'calculation\calculator.html', {'sum': sum})
else:
form = CalculationForm()
return render(request, 'calculation\calculator.html', {'form': form})
my HTML
<body>
<form method="get" action=".">{% csrf_token %}
{{ form }}
<input type="submit" name="Register" value="Submit" />
{{sum}}
</body>
Here I am showing the user simple form
user input numbers in two fields
Add the numbers
showing it back to the user on the same page
My form is getting rendered and the fields are displaying I am able to enter the number in the field but when I click submit I get an error. Anyone
When you get an error, you should show it in your question, rather than just saying "I get an error".
The main issue here is that the request method is always GET, because that's how your form is being submitted. So your if statement is always true, even on first display of the page.
You need to switch on something else. One idea would be to use the fact that the Submit button is an input like the others, so would be included in the submitted data. So:
if 'Submit' in request.GET:
form = CalculationForm(request.GET)
...
Note that you will have another error, when you call sum.save(). The sum here is an integer, so it's not clear what you are trying to do when you call "save" on it.
Related
I created an input form to get the data into web and use the inputs for an AP call.
When I want t refresh the page, there is a popup asking if you want to refresh the input. This is very annoying.
The solution was to use HttpResponseRedirect, which workout nicely, but it's throwing away all the inputs. Then the though would be to use variable in the URL with "URL?rds=2".
How do you get the input variables through the HttpResponseRedirect to the same site?
And also how to get variables from URL to input and from input to the URL?
HTML input definition:
<form action="{% url 'page' %}" method="post">
{% csrf_token %}
<input type="number" value="{{request.GET.rds}}" name='rds'>
<input type="submit" value="Search">
</form>
views.py:
Getting the data from the URL input
if 'rds' in request.GET.keys():
radius = request.GET.get('rds')
else:
request.GET.rds = '3'
radius = '3'
Redirecting input if user pressed. Add more variables with "&" if needed.
if request.method == 'POST':
radius = request.POST.get('rds')
redirect_link = request.path_info + '?rds=' + str(radius)
return HttpResponseRedirect(redirect_link)
This will redirect the radius to the same page and will put rds as a get attribute, which will be fatched by the if method.
Afterwards you can use the data with.
context = {'radius': radius}
return render(request=request, template_name='realestate/page.html', context = context)
I hope this is helpfull. Maybe there is also a way better solution then this.
Consider this :
{% for user in users.query.all() %}
<tr>
<form method='POST' action="">
<td>{{form.username}}</td>
<td>{{form.description}}</td>
<td>{{form.submit(value="Update")}}</td>
</form>
</tr>
{% endfor %}
For each user this will create a small form that I can update, I want to populate these forms with current database data
What I tried to do in the routes file:
#app.route("/Users")
def listUsers():
users = Users
form = UserForm()
if request.method == 'GET':
for user in users.query.all():
form.username.data = user.username
form.description.data = user.description
return render_template('Users.html', users=users, form=form)
This results in having the data of the last user populating all of the forms, how can I go about fixing this ?
I was thinking of assigning an id to each form that matchs the user, but how would I be able to send a dynamic number of forms ?
It took me a while, but I got a work around, just gonna post it if anyone else has the same issue:
I used javascript ... created a function and called it within the for loop which populated the fields for me
function populateForm(username,description){
var form = document.getElementById('form id here');
form.nextElementSibling.value = username;
form.nextElementSibling.nextElementSibling.textContent = description;
}
note that I used value for input field and textContent for textfield, then inside the for loop i added a script tag
<script>
populateForm('{{user.username}}','{{user,description}}');
</script>
I have a simple form and whenever the user does something wrong on the form I'd like to raise a validation error on Django. The problem is that I set up the form validation but when the form is submitted with wrong values, it goes through. I was wondering why it's happening and how I can avoid that?
Here is the html form:
<form id="ask-project" method="post" action="{% url 'ask-project' %}">
{% csrf_token %}
<input required="required" class="form-control form-text required" id="prenom" name="prenom" type="text">
<button class="btn btn-default submit">Submit</button>
</form>
views.py:
def askProject(request):
if request.method == 'POST':
form = AskProjectForm(request.POST)
if form.is_valid():
save_it = form.save(commit=False)
save_it.save()
return redirect('/merci/') #success
forms.py:
class AskProjectForm(forms.ModelForm):
class Meta:
model = AskProject
fields = ['prenom']
def clean_prenom(self):
prenom = self.cleaned_data['prenom']
if len(prenom) < 3:
raise ValidationError('Votre prénom doit etre plus long que 1 caractère.')
return prenom
Am I doing something wrong?
With the pattern that you are using, this sort of problem is inevitable and order of the day. The first thing is not to render the form manually as you appear to be doing. That means you are not showing any feedback when the user enters invalid data. Consider using {{ form }}, {{ form.as_table }} etc or rendering the fields with all information as described here: https://docs.djangoproject.com/en/1.11/topics/forms/#rendering-fields-manually
Second problem is that you are redirecting when the form is submitted, regardless of whether it's valid or not. The recommended pattern is to redirect only when the form is valid. So even if you apply the suggestion in the first para, you are still not getting the required feedback. Consider implementing the form as suggested in the manual. A straight copy past follows
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
Finally getting onto the specific case of why your form validation doesn't work, add a print statement in your clean method to print out both the string and it's length see if it tallies (or if your method even gets called)
I met this strange problem when doing a pre-populated form.
In my template, the form method is clearly stated as POST:
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">{% csrf_token %}
But in my view function, the request.method turns out to be GET.
Below is my view function:
def editProfile(request,template_name):
theprofile = request.user.profile
print theprofile.fullname
notificationMSG = ''
print request.method
if request.method == 'POST':
form = UserProfileForm(request.POST,request.FILES, instance=theprofile)
if form.is_valid():
form.save()
notificationMSG = "success!"
else:
form = UserProfileForm()
print "error"
dic = {'form':form,
'notificationMSG':notificationMSG}
return render_to_response(template_name, dic, context_instance=RequestContext(request))
When I run it, it prints out GET.
Anyone met this odd before?
In my case I was missing a "/" at the end of action in the HTML Template, while posting.
When you are loading the form and retrieving remote data by hitting a url, the request method is GET.
When you fill the form values and submit the form(with post method) i.e. insert/update remote data, the request method is POST.
So, in your code when you print request.method, the output is GET when you are loading the form. This has nothing to do with your pre-populated form.
Here are the steps I needed so far to solve this kind of error:
Add method="post" to your <form> element
Add a missing "/" at the end of the url at the action property on your <form> element
Add a type="submit" to your <button> element
Ps. Don't forget to add {% csrf_token %} after your <form>.
Every time I submitted my form with action="" I was getting a GET response, but once I filled the actual URL action="/client/" it went through as a POST.
I am also facing this problem but, In my case, in input type, I have written
type =" button" when I change it to type="submit" it get resolved.
Sorry, I get misunderstood when again I face the same problem then I got actual solution.
Heres the scenario:
I have a email subscriber/un-subscriber app. I am stuck up in the un-subscribing a user part. The user is given a link, which if he/she follows will be able to un-subscribe. The link is typically a view, in the following format:
r^'/unsub_view/(?P<user_id>\w+)/$'
So, when the user follows this links he/she is doing a GET request on the view unsub_view with a parameter user_id. So I have coded up my view as:
def unsub_view(request, user_id):
if request.method == 'GET':
### Do some DB lookup to determine if it is a valid user or not
if user_is_valid:
return direct_to_template(request, '/app/unsub.html', {'user': user})
Now when a valid user is doing the GET, a confirmation dialogue is shown, along with a button. If he/she clicks on the button, I want the template to post the 'user' to the same view, thus the unsub_view also has this piece of code:
if request.method == 'POST':
if user_is_subscribed:
#Unsubscribe the user.
else:
#Show error meessage.
My question is how can I have the button in my template to post to this view ? I have looked around but I got POST-ing to a .php or .asp
Please help.
Note: If there is a better workflow idea, I am also open to that, so please do suggest if there is one.
In the template unsub.html rendering the form with the button, you should pass the url of your view using the reverse method
from django.code.urlresolvers import reverse
def unsub_view(request, viewid):
if request.method == 'POST':
if user_is_subscribed:
#Unsubscribe the user.
submit_url = reverse('unsub_view', viewid)
return direct_to_template(request, '/app/unsub.html', {'user': user, 'submit_url'})
else:
#Show error meessage.
in your template you can then render the form like follows :
...
<form method='post' action='{{ submit_url }}'>
{% csrf_token %}
<input type="hidden" value="{{ user_id }}" name="user_id" />
<input type="submit" value="unsubscribe"/>
</form>
...
Django also has a full framework dedicated to form modeling and rendering. You could take advantage of that to generate the form.