Two buttons in one form connect two different python function - python

The problem is that I have two buttons in a form. Additionally, both buttons are running though the same function. How do i force the "Save" button to run though a different function when clicked?
I can post the python code later if necessary.
<form action="/predict" class="form-upload" method="post" enctype="multipart/form-data">
<h1 class="h3 mb-3 font-weight-normal">Please Upload Image</h1>
<input autofocus class="form-control" id="image" name="image" required type="file"><br>
<button type = "submit" name = "predict" formaction="/predict" class="btn btn-lg btn-primary btn-block">Predict</button>
<button type = "submit" name = "save" formaction = "/add" class="btn btn-lg btn-primary btn-block" >Save</button>
{% if image_loc %}
<img id="img" class="mb-4" src="static/{{ image_loc }}" alt="" width="256" height="256">
<h3 id="nm" class="h3 mb-3 font-weight-normal">Prediction: {{ p }}</h3><br>
{% endif %}
</form>

You can use formaction attribute on the button. It overrides the action attribute of the form.
MDN

Related

Django UserCreationForm and Bootstrap Forms Layouts

I am trying to extend the UserCreationForm using a Bootstrap layout style for the field username. After the input tag in the registration form, I would like to add a div element like an example that I have readapted from the Bootstrap page: i.e. suggesting the user to enter the same username as the company domain.
Let's focus to the bare minimum. The form readapted from Bootstrap is:
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
<div class="col-auto">
<div class="input-group">
<input type="text" name="username" class="form-control" placeholder="your.username" id="id_username">
<div class="input-group-text">#company.domain.com</div>
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
Which produces the following:
For the moment, I am using only {{form.as_p}} in my html template file:
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
{{form.as_p}}
<div class="col-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
And I don't know how to add the <div class="input-group-text">#company.domain.com</div> part embedded in a <div class="input-group">...</div> block.
My actual forms.py is a bit more complex, but readapted for this minimum example it contains the widget attributes as follows:
class SignupForm(UserCreationForm):
username = forms.CharField(label="",
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'your.username'}))
class Meta:
model = User
fields = (
'username',
)
Without additional libraries, is there a way to extend the widget attributes? Is it even possible to use {{form.as_p}} as I am currently doing or should I use another method?
If you want to use only {{ form.as_p }} with bootstrap then you need to install django-bootstrap.
Install it using pip:
pip install django-bootstrap4
After installation, add it in INSTALLED_APPS in settings.py file.
INSTALLED_APPS = [
'bootstrap4',
]
And in templates, you need to load it.
{% load bootstrap4 %}
{% bootstrap_messages %}
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
{% csrf_token %}
{% bootstrap_form form %} # added `form` here. we don't need to use with as_p.
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
This is the way you can use bootstrap along with {{ form.as_p }}
OR
Try another way:
Simply you can use {{ form.username }} inside an input tag in template.
For Example:
<input type="text" value="{{ form.username }}">
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
<div class="col-auto">
<div class="input-group">
<input type="text" name="username" class="form-control" placeholder="your.username" id="id_username" value="{{ form.username }}"> #Added here
<div class="input-group-text">#company.domain.com</div>
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>

Can't access an item in a dictionary that does in fact exist

I have two buttons on my page, each one in its own separate form.
One of the buttons, "deleteImage", works perfectly fine.
The other button, "search", won't work.
This is my response.POST when search is pressed.
request.POST <QueryDict: {'csrfmiddlewaretoken': ['randomtoken1234'], 'search': ['food', '']}>
request.POST.get("search") is failing to work for some reason, I tried printing it as well and nothing prints out.
my html
<form method="post" action="" class="form-group">
{% csrf_token %}
<div class="input-group mb-3">
{{form_search.search}}
<div class="input-group-append">
<button type="submit" class="btn btn-primary" name="search">Search!</button>
</div>
</div>
Looking at the QueryDict the key search is shown as 'search': ['food', '']. This means there are two values posted for search where one is an empty string.
I assume that this is because other than your button the form field for the search input is also named search. When one writes request.POST.get("search") they get the last value for the given key which here is an empty string for you (the value of the button).
The solutions are:
Change the name of the form field from search to something else.
Change the name of the submit button from search to something else. Which will be something like:
<form method="post" action="" class="form-group">
{% csrf_token %}
<div class="input-group mb-3">
{{form_search.search}}
<div class="input-group-append">
<!-- Change name attribute of button -->
<button type="submit" class="btn btn-primary" name="search-pressed">Search!</button>
</div>
</div>
</form>
Note that you might need to make some changes in your view as well to reflect these changes in the name.
Fixed by adding a value to the search button
<form method="post" action="" class="form-group">
{% csrf_token %}
<div class="input-group mb-3">
{{form_search.search}}
<div class="input-group-append">
<button type="submit" class="btn btn-primary" name="search" value="{{form_search.search}}">Search!</button>
</div>
</div>
</form>

Why does adding Bootstrap stop my Flask application from working?

I am learning Flask for the first time so I created a basic application of adding names into an unordered list. The names which is inserted are taken input in a input field. Basically when I didn't add Bootstrap it was working fine but when I added Bootstrap it is doing nothing when I click the button.
Code when no Bootstrap
<form action="{{ url_for('index') }}" method="POST">
<input type="text" name="name" placeholder="Enter your name" style="border-radius: 20px;">
<button>Click Me!</button>
</form>
<ul>
{% for item in task %}
<li> {{ item }} </li>
{% endfor %}
</ul>
Code when Bootstrap added :
<form action="{{ url_for('index') }}" method="POST">
<div class="input-group col-lg-10 col-sm-6">
<input type="text" name="name" class="form-control" placeholder="Enter your name"
style="border-radius: 20px;">
<span class="input-group-btn">
<button class="btn btn-primary" type="button">Click Me!</button>
</span>
</div>
</form>
<ul>
{% for item in task %}
<li> {{ item }} </li>
{% endfor %}
</ul>
This is my application.py :
from flask import Flask
from flask import render_template,request
app = Flask(__name__)
task=[]
#app.route("/",methods=["GET","POST"])
def index():
if request.method=="POST":
name = request.form.get("name")
task.append(name)
return render_template("index.html",task=task)
Your problem probably is not Bootstrap but type="button".
If you use type="button" in <button> even without Bootstrap then you have the same problem.
You have to remove it or use type="submit".
In <button> you can use only
type="submit" to send form to server
type="reset" to clear form (without sending to server)
type="button" to create clickable button but it doesn't send to server and you can assign JavaScript code which run some function after clicking.
BTW: I'm not sure but maybe Bootstrap has some JavaScript file which you has to link in HTML to change button behavior when you use type="button".
Minimal working example
from flask import Flask
from flask import render_template_string, request
app = Flask(__name__)
#app.route("/", methods=["GET","POST"])
def index():
if request.method=="POST":
name = request.form.get("name")
print(name)
return render_template_string("""<form action="{{ url_for('index') }}" method="POST">
<input type="text" name="name" placeholder="Enter your name">
<br>
<button>Button without Type</button>
<br>
<button type="submit">Button type="Submit"</button>
<button type="reset">Button type="Reset"</button>
<button type="button">Button type="Button"</button>
<button type="button" onclick="alert('Clicked')">Button type="Button" with JavaScript</button>
<br>
<input type="submit" value='Input type="Submit"'/>
<input type="reset" value='Input type="Reset"'/>
<input type="button" value='Input type="Button"'/>
<input type="button" onclick="alert('Clicked')" value='Input type="Button" with JavaScript"'/>
</form>""")
app.run()
Doc: < button >, < input >
Change <button> to <input type=“submit” value=“Click Me! />. You can add whatever bootstrap classes you want to style this submit input like a button.

disable validation in back button in django form

I have a form representing a quiz with some questions and a result that appears in the end in Django 1.10. I need t implement two other buttons next to the "Check" button, one of them is "Mark" and the other is "Back".
When I click on "back", I m handling well its behavior in the view but a pop up appears saying "Please Select One Of these Options".
I need to disable it since user should not select one of the radio buttons if going back to the previous question.
<form action="" method="POST">
{% csrf_token %}
<input type=hidden name="question_id" value="{{ question.id }}">
<ul class="list-group">
{% for answer in form.answers %}
<li class="list-group-item" >{{ answer }}</li>
{% endfor %}
</ul>
<div id="buttons">
<input type="submit" name="question_btn" value={% trans "Check" %} class="btn btn-lg center-block btn-outline btn-success" required>
<input type="submit" name="question_btn" value={% trans "Back" %}
class="btn btn-lg center-block btn-outline btn-success" required>
Any idea?
The back button shouldn't be an input and a type="submit". Just make it a button or a a element and that would work nicely.

Receiving HTML request from Bootstrap <button>

<form method="post" class="form-horizontal" role="form">
<div class="btn-group col-sm-3">
<button id="typeSelect" type="button" name="reportType" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
People <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>
...
</li>
...
</ul>
</div>
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label">Name</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="inputName" placeholder="Name" name="name" value="{{name}}" onblur="isEmpty(this)">
</div>
</div>
</form>
I have two inputs in my form and I am trying to get the input in my Python code.
report_type = self.request.get('reportType')
name = self.request.get('name')
name is working correctly, but report_type will always be None.
What is the correct way to retrieve the selection in a button (Bootstrap)?
According to the button element specifications:
A button (and its value) is only included in the form submission if the button itself was used to initiate the form submission.
You will have to find another way to pass the value of the button. You could, for example, store the value in a hidden field.

Categories