How to show confirmation modal in Flask app after form submission? - python

I'm trying to show a confirmation/success message to the user in my Flask app, but I can't figure out how to display it in a modal.
#app.route("/", methods=["POST"]
def sendForm():
form = ContactForm(request.form)
if request.method == 'POST':
if form.validate():
# do stuff with form data
return render_template("contact.html", form=form)
else:
# display error message
else:
return render_template("index.html")
The part where I return the contact.html template is where I need help, I think. Because that page is basically refreshed and shown again after the POST request successfully completes. Need to display a confirm message to the user in a modal instead.
On the front-end, my form is looks like this:
<form method="POST" action="{{ url_for('sendForm') }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
{{ render_field(form.email) }}
{{ render_field(form.name) }}
<input id="submit-form" type="submit" value="Send">
</form>

I would do some form of this...
Pass a boolean in your render_template:
submission_successful = True #or False. you can determine this.
render_template("contact.html", form=form, submission_successful=submission_successful))
Then in your template place an if statement
{% if submission_successful %}
// modal elements here
{% endif %}

Related

Failure in multiple times Parameters Passing in Django (Python)

I am new to django. My current plan is displaying user name on different html pages, once user have successfully logged in. At the moment, the page after login page can successfully display the user name with the django tag in html which is {{ username }}. But once it has successfully passed to my second page, my second page CAN NOT pass it to my third page. The attached images are my html codes for second.html and third.html. Thanks for your help.
Second.html
<form action="/SecondPageSub/" method="POST">
{% csrf_token %}<br>
<b>NTID:</b><br>
<label name="usrnm">{{username}}</label>
<button type="submit" name="SecondPageSub">
SUBMIT
</button>
</form>
Third.html
<form action="/ThirdPageSub/" method="POST">
{% csrf_token %}<br>
<b>NTID:</b><br>
<label name="usrnm">{{username}}</label>
<button type="submit" name="ThirdPageSub">
SUBMIT
</button>
</form>
Python codes in view.py
def ActionGet(request):
if request.method == "POST":
if 'login' in request.POST:
usrname = request.POST.get("usrnm", None)
passwrd = request.POST.get("pwd", None)
dic={}
dic['username']=usrname
dic['password']=passwrd
return render(request, "Second.html",dic)
if 'SecondPageSub' in request.POST:
usrname = request.POST.get("usrnm", None)
dic={}
dic['username']=usrname
return render(request, "Third.html",dic)
if 'ThirdPageSub' in request.POST:
usrname = request.POST.get("usrnm", None)
dic={}
dic['username']=usrname
return render(request, "Forth.html",dic)
by default django gives you {{ request.user.username }} through out your templates. So you can call it on any templates
You aren't passing the usrnm in your post request with SUBMIT on your SecondPageSub

Flask does not take WTForms input

I'm tring to create an app with flask with WTForms.
In the controller.py i have:
#mod_private.route('/portfolio/', methods=['GET', 'POST'])
#login_required
def portfolio():
print "in portfolio" # I read this
form = CreateCoinsForm(request.form)
if request.method == 'POST' and form.validate_on_submit():
print form.coins.data #I cannot take this value
return render_template("private/portfolio.html",form=form)
return render_template("private/portfolio.html",form=form)
in the forms.py:
class CreateCoinsForm(Form):
coins = IntegerField('coins',
[DataRequired('num required'),
NumberRange(min=0, max=10)])
and the template
<form method="post" action="/private/portfolio/" accept-charset="UTF-8" role="form">
<p> {{ form.coins }}</p>
<p><input type=submit value=Generate>
</form>
my problem, as i wrote in the code is that I cannot retrieve the string inserted in the template.
Your problem suggests that you are using the built-in CSRF protection on your form, and your form actually isn't validating because you haven't included the CSRF token.
Try adjusting your template like so:
<form method="post" action="/private/portfolio/" accept-charset="UTF-8" role="form">
{{ form.hidden_tag() }}
<p> {{ form.coins }}</p>
<p><input type=submit value=Generate>
</form>

Django/Python: How to pass a variable from a form to a python script with POST method?

I'm getting this error when submit:
CSRF verification failed. Request aborted.
I've got this far following the documentation, but I don't fully understand it and it's definitely wrong. I just want to take a query word from my search box(form) and pass it to a python script as an argument. I'm new to Django and getting stuck on the easiest things.
In models.py:
class QueryForm(forms.Form):
query = forms.CharField(label='query',max_length=100)
I added this line to my urls.py
url(r'^results/$', 'tweemo.views.results'),
On my homepage where my search box is I have this code for my form:
<form action="/home/results/" method="post">
<label for="query">Search:</label>
<input id="query" type="text" name="query" value="{{ current_query }}">
<input type="submit" value="ok">
</form>
In views.py I added these two functions:
def get_query(request):
if request.method == 'POST':
form = QueryForm(request.POST)
if form.isvalid():
return HttpResponseRedirect('/thanks/')
else:
form = QueryForm()
return render(request, 'results.html', {'form': form})
def results(request):
return render_to_response('results.html',{'here':TwitterStream.objects.all() })
MY results.html contains just this:
<form action="/home/results/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit"/>
</form>
You must just add the {% csrf_token %} tag inside EVERY <form></form> tag which has method to be post in your template.
So the below markup should be corrected:
<form action="/home/results/" method="post">
{% csrf_token %}
<label for="query">Search:</label>
<input id="query" type="text" name="query" value="{{ current_query }}">
<input type="submit" value="ok">
</form>
Well the problem is that you are not passing the csrf token to the form , you need to pass the csrf token to the render function in order for it to be applied in the form . To accomplish this you need to associate the csrf token to the request.
def get_query(request):
if request.method == 'POST':
form = QueryForm(request.POST)
if form.isvalid():
return HttpResponseRedirect('/thanks/')
else:
form = QueryForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('results.html', args)
def results(request):
return render_to_response('results.html',{'here':TwitterStream.objects.all() })

Nested Django Forms: 'ManagementForm data is missing or has been tampered with'

So i've looked around and it seems nobody has had the same problem that I am having to cause this seemingly common error. I am rendering some forms in my html as follows:
<form method="post" action="">
{{ tags_formset.management_form }}
<!-- code displaying this formset -->
...
<!-- -->
<form method="post" action="">
{{ add_all_form.management_form }}
{{ add_all_form.addTagsToAll }}
<input type="submit" value="Add To Displayed Applicants" />
</form>
<form method="post" action="">
{{ remove_all_form.management_form }}
{{ remove_all_form.removeTagsFromAll }}
<input type="submit" value="Remove From Displayed Applicants" />
</form>
<input type="submit" value="Save Changes" />
</form>
When i did not have the two inner forms the formset is displayed correctly and the submit button works to submit the form. When i added the 2nd two forms a couple of problems occured:
-The submit button stopped working (though pressing enter while one of the formset's fields is selected still submits the form
-The add_all_form's submit works and it functions propperly (not a problem but interesting concerning the next point...)
-The remove_all_form does not work ad throughs the 'ManagementForm data is missing or has been tampered with' validation error.
Here is the views.py code that creats the forms:
TagsFormSet = formset_factory(TagsForm, formset=TagFormSet, extra=applicantQuery.count())
if request.method == 'POST':
tags_formset = TagsFormSet(request.POST, request.FILES, prefix='tags', applicants=applicantQuery)
add_all_form = TagAddAllForm(request.POST, request.FILES, prefix='addForm', applicants=applicantQuery)
remove_all_form = TagRemoveAllForm(request.POST, request.FILES, prefix='removeForm', applicants=applicantQuery)
redirect = False
if tags_formset.is_valid():
for tagForm in tags_formset.forms:
if 'tags' in tagForm.cleaned_data:
tagForm.saveTags()
if 'removeTags' in tagForm.cleaned_data:
tagForm.deleteTags()
redirect = True
if add_all_form.is_valid():
if 'addTagsToAll' in add_all_form.cleaned_data:
add_all_form.saveTagsToAll()
redirect = True
if remove_all_form.is_valid():
if 'removeTagsFromAll' in remove_all_form.cleaned_data:
remove_all_form.deleteTagsFromAll()
redirect = True
if redirect:
return http.HttpResponseRedirect('')
else:
initForms = []
tags_formset = TagsFormSet(prefix='tags', applicants=applicantQuery)
add_all_form = TagAddAllForm(prefix='addForm', applicants=applicantQuery)
remove_all_form = TagRemoveAllForm(prefix='removeForm', applicants=applicantQuery)
I literally can not figure out what is going wrong. I don't know why the add_all_form works when the remove_all_form does not, as i basically copy and pasted everything involved (if you need i can post the code from the Forms.py file but I don't think the problem is there...)
Please help!
You should use only one <form> tag. You can have as many submit button as you want here and can display as many forms as you want, but all should be inside a single <form> tag.
Then all the management data will be sent properly in form submit and your issue should be fixed.
<form method="post" action="">
{{ tags_formset.management_form }}
<!-- code displaying this formset -->
...
<!-- -->
{{ add_all_form.management_form }}
{{ add_all_form.addTagsToAll }}
<input type="submit" value="Add To Displayed Applicants" />
>
{{ remove_all_form.management_form }}
{{ remove_all_form.removeTagsFromAll }}
<input type="submit" value="Remove From Displayed Applicants" />
<input type="submit" value="Save Changes" />
Your view can remain as it is.

Django form errors are not showing up

I have looked all over stackoverflow and the Internet about this so I will just show my code.
views.py
def UserSell(request,username):
theuser=User.objects.get(username=username)
thegigform=GigForm()
#if the user is submitting a form
if request.method=='POST':
#bind form with form inputs and image
gigform=GigForm(request.POST,request.FILES)
if gigform.is_valid():
gigform.title=gigform.cleaned_data['title']
gigform.description=gigform.cleaned_data['description']
gigform.more_info=gigform.cleaned_data['more_info']
gigform.time_for_completion=gigform.cleaned_data['time_for_completion']
gigform.gig_image=gigform.cleaned_data['gig_image']
finalgigform=gigform.save(commit=False)
finalgigform.from_user=theuser
finalgigform.save()
return HttpResponseRedirect('done')
thegigform=GigForm()
context=RequestContext(request)
return render_to_response('sell.html',{'theuser':theuser,'thegigform':thegigform},context_instance=context)
template
<form action="{% url sell user.username %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset>
<legend><h2>Sell A Gig</h2></legend>
{% for f in thegigform %}
<div class="formWrapper">
{{f.errors}}
{{f.label_tag}}: {{f}}
{{f.help_text}}
</div>
{% endfor %}
</fieldset>
<input type="submit" value="Sell Now!" />
This code seems to follow normal django form protocol so please tell me why my django template doesnt show the errors. Thanks
It looks like you are missing an else block.
if gigform.valid() returns false, you are overwriting the variable "thegigform". Try restructuring your code like this:
if request.method=='POST':
#bind form with form inputs and image
thegigform=GigForm(request.POST,request.FILES)
if thegigform.is_valid():
thegigform.title=gigform.cleaned_data['title']
thegigform.description=gigform.cleaned_data['description']
thegigform.more_info=gigform.cleaned_data['more_info']
thegigform.time_for_completion=gigform.cleaned_data['time_for_completion']
thegigform.gig_image=gigform.cleaned_data['gig_image']
finalgigform=gigform.save(commit=False)
finalgigform.from_user=theuser
finalgigform.save()
return HttpResponseRedirect('done')
else:
thegigform=GigForm()
context=RequestContext(request)
return render_to_response('sell.html',{'theuser':theuser,'thegigform':thegigform},context_instance=context)

Categories