Handling POST request Flask - python

I am trying to pass data from my website's login page as a POST request to Flask. However, Flask fails to obtain any data. Here's a code snippet of my test.py file that runs the Flask app. I realised that the code isn't entering the method itself.Can anyone help me understand where am I going wrong?
#app.route('/', methods=['POST'])
def my_form_post():
text = request.form['text']
processed_text = text.upper()
print "Processed text is..."
print processed_text
return processed_text
Here's the snippet of my login form:
div class="modal fade" id="direct-login-form" tabindex="-1" role="dialog" aria-labelledby="direct-login-form-label" aria-hidden="true">
<div class="vertical-alignment-helper">
<div class="modal-dialog vertical-align-center">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span>
</button>
<h4 class="modal-title" id="direct-login-form-label">Login</h4>
</div>
<div class="modal-body">
<div class="wrap-login-form wrap-reviews">
<form id="direct-login" form action="." method="POST" class="form-horizontal">
<div class="form-group">
<label class="col-sm-3" for="direct_username">Username</label>
<div class="col-sm-9">
<input type="text" name="text" class="form-control" id="direct_username" placeholder="Username">
</div>
</div>
<div class="form-group">
<label class="col-sm-3" for="direct_password">Password</label>
<div class="col-sm-9">
<input type="password" class="form-control" id="direct_password" placeholder="Password">
</div>
</div>
<div class="wrap-slidecheck clearfix">
<div class="col-sm-3"></div>
<div class="col-sm-9">
<div class="slidecheck">
<input type="checkbox" id="direct_remember_me" name="check" />
<label for="direct_remember_me"></label>
</div>
<span>Remember me</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3"></label>
<div class="col-sm-9">
<button type="submit" name="my-form" class="btn btn-default" value="Send">Submit</button>
</div>
</div>
<div class="form-group">
<label class="col-sm-3"></label>
<div class="col-sm-9">
<p class="help-block">Lost your password?<span> or </span>Register an Account</p>
</div>
</div>
<input type="hidden" id="direct_security" name="direct_security" value="f0abedaf74" /><input type="hidden" name="_wp_http_referer" value="/directory-category/coffee-lounge/" /> </form>
</div>
</div>
</div>
</div>
</div>
</div>

I simulated your problem on my machine it worked !
I made the following changes.
for view
#app.route("/")
def hello():
return render_template('register.html')
#app.route("/register", methods=['POST'])
def register():
text = request.form['text']
passwd = request.form['passwd']
processed_text = text.upper()
print "Processed text is...", processed_text, passwd
#do your further processing like saving to Database...
return render_template('register.html') #send to the profile/dashboard page
for html file
<form id="direct-login" form action="{{ url_for('register') }}" method="POST" class="form-horizontal">
<input type="password" class="form-control" id="direct_password" name='passwd' placeholder="Password">
However you should use WTF forms you will have a clean and reusable code with that.
an example forms.py
class RegistrationForm(Form):
email = StringField('Email', validators=[Required(), Email(), Length(1, 64)])
username = StringField('Username', validators=[Required(), Length(1, 64), Regexp('^[A-Za-z][A-za-z0-9._]*$', 0,'Username must have only letters, dots, digitsm or underscores')])
password = PasswordField('Password', validators=[Required(), EqualTo('password2', message='Password must match.')])
password2 = PasswordField('Confirm Password', validators=[Required()])
submit = SubmitField('Register')
'''
Custome validator for email validate_*
'''
def validate_email(self, field):
if(User.query.filter_by(email= field.data)).first():
raise ValidationError('Email already registered.')
'''
Custome validator for email validate_*
'''
def validate_username(self, field):
if(User.query.filter_by(username = field.data)).first():
raise ValidationError('Username already registered.')
then your html becomes
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %} - Register{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Register</h1>
</div>
<div class="col-md-5">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}

The line containing the opening tag for your form seems like the suspect here:
<form id="direct-login" form action="." method="POST" class="form-horizontal">
While I'm not sure if the floating form attribute is causing any issues, I'm certain that it isn't doing anything useful so you should get rid of that.
Also, by specifying action=".", you are saying that the submission of the form should be directed to the same route that you got the form from. In your Flask code, you wrote
#app.route('/', methods=["POST"])
so in your form tag, you should specify action="/" for the submission to go to the my_form_post method in Flask.

Related

Why aren't changes saved when editing a Django product?

Created a website with products. I need to make a window for editing them on the site in order to change the manufacturer and other characteristics. This must be done in a pop-up window. I have data displayed, I change it, but nothing changes when I save it. How can this problem be solved.
My vievs:
def parts(request):
added = ''
error = ''
PartAllView = Part.objects.order_by('-id')
if request.method == 'POST' and 'parts_add' in request.POST:
form = PartForm(request.POST, request.FILES)
if form.is_valid():
form.save()
added = 'Добавлено'
else:
error = 'Данная запчасть уже добавлена'
if request.method == 'POST' and 'parts_edit' in request.POST:
PartPost = int(request.POST['parts_edit'])
PartID = Part.objects.get(id=PartPost)
if PartID:
PartID.save()
added = 'Запчасть успешно отредактирована'
else:
error = 'Ошибка редактирования'
form = PartForm()
data = {
'added': added,
'error': error,
'form': form,
'PartAllView': PartAllView,
}
return render(request, 'kross/parts.html', data)
My HTML:
{% if PartAllView %}
{% for el in PartAllView %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal fade" id="partEdit{{ el.id }}">
<div class="modal-dialog modal-dialog-centered text-center" role="document">
<div class="modal-content modal-content-demo">
<div class="modal-header">
<h6 class="modal-title">Добавление запчасти</h6><button aria-label="Close" class="btn-close"
data-bs-dismiss="modal"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<div class="row row-sm">
<div class="col-lg-6">
<div class="form-group">
<input type="text" class="form-control" name="brand" value="{{ el.brand }}">
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<input type="text" class="form-control" value="{{ el.number }}">
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<input type="text" class="form-control" value="{{ el.name }}"><br>
<input type="textarea" class="form-control" rows="2" value="{{ el.description }}">
</div>
</div>
</div>
{{ el.analog }}
...
You can use updateView to edit an existing data in your website by simply:
from django.views.generic.edit import UpdateView
From MyApp models import #Model
class editview(UpdateView):
model = #Your Model You want to edit
fields = [#Add the fields you want to edit]
template_name = 'edit.html'
success_url = ('Home')
In your edit Template add:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update">
I hope it help.

How to pass bootstrap modal input data from HTML to Python Flask

I have a modal popup that allows users to input data. I want to pass that data to Flask so that I can put it in my database. For some reason, no data is being passed. I am printing out request.form and it logs "ImmutableMultiDict([])", when it should contain my form's inputs. I have been trying to use POST, but I'm open to other ideas. This is happening on Heroku, I haven't tested it locally.
HTML
<!-- Modal -->
<div class="modal fade" id="newProjectModal" tabindex="-1" aria-labelledby="newProjectModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="newProjectModalLabel">Create Project</h5>
<button type="button" class="btn-close" aria-label="Close"></button>
</div>
<form action="/createproject/" name="createProjectForm" id="createProjectForm" method="POST">
<div class="modal-body">
<div class="mb-3">
<label for="projectNameInput" class="form-label">Project Name</label>
<input type="text" class="form-control" id="projectNameInput" name="projectName" placeholder="New Project">
</div>
<div class="mb-3">
<label for="projectDescriptionInput" class="form-label">Project Description</label>
<textarea class="form-control" id="projectDescriptionInput" name="projectDescription" rows="3"></textarea>
</div>
<label for="selectUsersInput" class="form-label">Assign Personnel</label>
<select class="form-select" id="selectUsersInput" name="selectUsers" multiple aria-label="multiple select example">
{% for user in users %}
<option value="{{ user }}">{{ user }}</option>
{% endfor %}
</select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary">Close</button>
<button class="btn btn-primary" type="submit" name="submit" value="Submit">Create Project</button>
</div>
</tr>
</form>
</div>
</div>
</div>
Python
#app.route('/createproject/', methods=['POST'])
def createproject():
if request.method == 'POST':
print(request.form)
project_name = request.form.get('projectName')
project_description = request.form.get('projectDescription')
return '''
<h1>The name value is: {}</h1>
<h1>The description value is: {}</h1>'''.format(project_name, project_description)
project_name and project_description are always "None" instead of the entered value

Django-Vue error "Failed to mount app: mount target selector returned null."

Thanks for looking into my problem, I am a beginner with Django and Vue your assistance with this wil be extremely helpful. I am working on a Job portal and created the job search functionality in Django as backend for the same I have an app called job into my Django project. The browser Js console gives this error Failed to mount app: mount target selector returned null. For this app I have an add job view, through which an employer adds the jobs. For this I'm using Vue for validation and showing any errors if any non-null fields are not entered by the employer account. So this is not how it was supposed to look,Unexpected results snap shot so as you can see it wasn't supposed to give me [[error]] and company_size instead The company size is missing as per the Vue AddJobApp, given below. Also if were to add # within mount-function-createapp within Vue-AddJobApp, the page entirely disappears (blank page). what am I doing wrong here?
adding # in AddJob.mount() function is making the page go blank a
Add job template
{% extends 'core/base.html' %}
{% block content %}
<div id="add-job-app">
<h1 class="title"> Add Job</h1>
<form action="." method="POST" v-on:submit="validateForm">
{% csrf_token %}
{% if form.errors %}
{% for error in form.errors %}
<div class="notification is-danger">
{{ error }}
</div>
{% endfor %}
{% endif %}
<div class="notification is-danger" v-if ="error.length" >
<p v-for="error in errors" >
[[ error ]]
</p>
</div>
<div class="field">
<label for="">Title</label>
<div class="control">
<input class="input" type="text" name="title" id="id_title" v-model= "title">
</div>
</div>
<div class="field">
<label for="">Short description</label>
<div class="control">
<textarea name="short_description" id="id_short_description" class="textarea" v-model= "short_description" ></textarea>
</div>
</div>
<div class="field">
<label for="">Long description</label>
<div class="control">
<textarea name="long_description" id="id_long_description" class="textarea" v-model= "long_description" ></textarea>
</div>
</div>
<div class="field">
<label for="">Company name</label>
<div class="control">
<input class="input" type="text" name="company_name" id="id_company_name" v-model= "company_name" >
</div>
</div>
<div class="field">
<label for="">Company address</label>
<div class="control">
<input class="input" type="text" name="company_address" id="id_company_address" v-model= "company_address">
</div>
</div>
<div class="field">
<label for="">Company zipcode</label>
<div class="control">
<input class="input" type="text" name="company_zipcode" id="id_company_zipcode" v-model= "company_zipcode">
</div>
</div>
<div class="field">
<label for="">Company place</label>
<div class="control">
<input class="input" type="text" name="company_place" id="id_company_place" v-model= "company_place">
</div>
</div>
<div class="field">
<label for="">Company Country</label>
<div class="control">
<input class="input" type="text" name="company_country" id="id_company_country" v-model= "company_country">
</div>
</div>
<div class="field">
<label for="">Company Size</label>
<div class="control">
<div class="select">
<select name="company_size" v-model = "company_size">
<option value="">Choose Size</option>
<option value="size_1_9">1-9</option>
<option value="size_10_49">10-49</option>
<option value="size_50_99">50-99</option>
<option value="size_100">100+</option>
</select>
</div>
</div>
</div>
<div class="field">
<div class="control">
<button class="button is-success">Submit</button>
</div>
</div>
</form>
</div>
{% endblock %}
{% block scripts %}
<script >
const AddJobApp = {
data() {
return {
title:'',
company_name:'',
short_description:'',
company_size:'',
errors:[]
}
},
delimiters:['[[',']]'],
methods :{
validateForm(e){
this.errors = []
if( this.title ===''){
this.errors.push('The title field is missing')
}
if( this.short_description ===''){
this.errors.push('The short description field is missing')
}
if( this.company_name ===''){
this.errors.push('The company name field is missing')
}
if( this.company_size ===''){
this.errors.push('The company size is missing')
}
if(this.errors.length){
e.preventDefault()
return false
}else{
return true
}
}
}
}
Vue.createApp(AddJobApp).mount('add-job-app');
</script>
{% endblock %}
my views.py file inside of job app
from apps.job.forms import AddJobForm, ApplicationForm
from django.shortcuts import redirect, render
from .models import Job
from django.contrib.auth.decorators import login_required
from apps.notification.utilities import create_notification
def job_detail(request,job_id):
job = Job.objects.get(pk=job_id)
return render(request, 'job/job_detail.html',{'job':job})
def search(request):
return render(request,'job/search.html')
#login_required
def apply_for_job(request,job_id):
job = Job.objects.get(pk=job_id)
if request.method=='POST':
form = ApplicationForm(request.POST)
if form.is_valid():
application = form.save(commit=False)
application.job = job
application.created_by = request.user
application.save()
create_notification(request, job.created_by ,'application',extra_id=application.id)
return redirect('dashboard')
else:
form = ApplicationForm()
return render(request,'job/apply_for_job.html',{'form':form,'job':job})
#login_required
def add_job(request):
if request.method=='POST':
form = AddJobForm(request.POST)
if form.is_valid():
job = form.save(commit=False)
job.created_by = request.user
job.save()
return redirect('dashboard')
else:
form = AddJobForm()
return render(request,'job/add_job.html',{'form':form})

Form is not responding to submit

I have form, user must fill it and submit but I have no reaction from this form
First I thought there is a problem with action directive of the form, so used redirect method in the views but no help
def organization_info(request):
organization_form = OrganizationInformationForm()
context = {
'organization_form': organization_form
}
if request.method == "POST":
print("POST")
organization_form = OrganizationInformationForm(request.POST, request.FILES)
if organization_form.is_valid():
print("VALID")
new_org = OrganizationInformation.objects.create(**organization_form.cleaned_data)
print("FILLED")
return redirect(organization_list)
return render(request, 'organization_form.html', context)
<form method="POST" enctype="multipart/form-data" class="form-horizontal">
{% csrf_token %}
<div class="form-group">
<label for="name" class="col-sm-4 control-label">Organization Name:</label>
<div class="col-sm-4">
{{ organization_form.name }}
</div>
.
.
<div class="form-group">
<div class="col-sm-4 col-sm-offset-4">
<button type="submit" class="btn btn-pink">Submit</button>
</div>
</div>
</form>
I only have the "POST" printed on the log no any errors
add form handler path in action and try again
<form method="POST" enctype="multipart/form-data" class="form-horizontal" action={'your form handler path'}>
{% csrf_token %}
<div class="form-group">
<label for="name" class="col-sm-4 control-label">Organization Name:</label>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-4">
<button type="submit" class="btn btn-pink">Submit</button>
</div>
</div>
</form>
You need to add an action attribute to your form.
<form method="POST" enctype="multipart/form-data" class="form-horizontal" **action="url-of-handler"**>
</form>
More on this topic: https://www.w3schools.com/tags/att_form_action.asp

Django view not getting post param

I know its basic but I got stuckl because of it I internet did not help me.
This is snippet of my django class based view (django 1.7)
def post(self, request,*args, **kwargs):
context = RequestContext(request, {})
print request.POST
print request.POST['search_text']
In html
<form method="post" action="{% url 'storage_place' %}">{% csrf_token %}
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<input type="text" class="form-control" id="search_text" name="search_text " placeholder="Key words...">
</div>
</div>
<div class="col-md-3">
<div class="s_btngroup">
<div class="col-md-6 col-sm-4 col-xs-5">
<input type="submit" class="btn ft_default-btn-red ft_primary-btn-mini" value="Search" />
</div>
</div>
</div>
</div>
</div>
</form>
When I do
print request.POST
It is printing
QueryDict: {u'csrfmiddlewaretoken': [u'GInHZCd4UK8oWjs2txgppCNEof3VC8zy'], u'search_text ': [u'defrghj']}
But in very next line when I do
print request.POST['search_text']
I am getting multivalue dict error.
Please tell me what would be the reason for this.
There's a trailing space after 'search_text ' in the <input.../>'s name attribute in your template:
<input type="..." class="..." id="..." name="search_text "
^
And you'll notice it appears in the QueryDict with the trailing space. You should remove the space.

Categories

Resources