Django: How can I call a view function from template? - django

I have a question on how to call a view function from a template HTML button? Like an onclick function?
Here is the template:
<input id="submit" type="button" onclick="xxx" method="post" value="Click" />
And the views.py is:
def request_page(request):
...do something...
return render_to_response("/directory.html", {})
Thank you very much.

Assuming that you want to get a value from the user input in html textbox whenever the user clicks 'Click' button, and then call a python function (mypythonfunction) that you wrote inside mypythoncode.py. Note that "btn" class is defined in a css file.
inside templateHTML.html:
<form action="#" method="get">
<input type="text" value="8" name="mytextbox" size="1"/>
<input type="submit" class="btn" value="Click" name="mybtn">
</form>
inside view.py:
import mypythoncode
def request_page(request):
if(request.GET.get('mybtn')):
mypythoncode.mypythonfunction( int(request.GET.get('mytextbox')) )
return render(request,'myApp/templateHTML.html')

One option is, you can wrap the submit button with a form
Something like this:
<form action="{% url path.to.request_page %}" method="POST">
<input id="submit" type="button" value="Click" />
</form>
(remove the onclick and method)
If you want to load a specific part of the page, without page reload - you can do
<input id="submit" type="button" value="Click" data_url/>
and on a submit listener
$(function(){
$('form').on('submit', function(e){
e.preventDefault();
$.ajax({
url: $(this).attr('action'),
method: $(this).attr('method'),
success: function(data){ $('#target').html(data) }
});
});
});

How about this:
<a class="btn btn-primary" href="{% url 'url-name'%}">Button-Text</a>
The class is including bootstrap styles for primary button.

you can put the input inside a form like this:-
<script>
$(document).ready(function(){
$(document).on('click','#send', function(){
$('#hid').val(data)
document.forms["myForm"].submit();
})
})
</script>
<form id="myForm" action="/request_page url/" method="post">
<input type="hidden" id="hid" name="hid"/>
</form>
<div id="send">Send Data</div>

For deleting all data:
HTML FILE
class="btn btn-primary" href="{% url 'delete_product'%}">Delete
Put the above code in an anchor tag. (the a tag!)
url.py
path('delete_product', views.delete_product, name='delete_product')]
views.py
def delete_product(request):
if request.method == "GET":
dest = Racket.objects.all()
dest.delete()
return render(request, "admin_page.html")

For example, a logout button can be written like this:
<button class="btn btn-primary" onclick="location.href={% url 'logout'%}">Logout</button>
Where logout endpoint:
#urls.py:
url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),

Related

Django - button redirecting to {% url 'index' %}

I can't find any solution on any article so I'm asking here.
I'd like to make button which is gonna redirect user to specific url.
I have already did it this way:
<button onclick="location.href='create_recipe/'" type="button" >Create new Recipe</button>
but instead of passing whole link I'd like to use {% url 'some_view' %} but I do not have an idea how I should do that.
Is it even possible to do that ?
It has to be <button>,
edit:
something like:
<button type="button" class="btn btn-outline-secondary">Create new Recipe</button>
also does not work
You can do this by adding this to the button:
onclick="goToSomeView()"
And then add this in script tag of html file:
<script type="text/javascript">
function goToSomeView(){
document.location.href = "{% url 'some_view' %}"
}
</script>
index is your function which exist views.py file.
from django.urls import path
from . import views
path('',views.index, name='index'),
HTML:
<a class="btn btn-outline-secondary" href="{% url 'index' %}">Create new Recipe</a>
As I see you're using bootstrap already, so the easiest way is to use the a element with the type="button" attribute.
Create new recipe
Below you can see that the result is the same, but for button you need to bind the onclick function. In this case I pointed to #nigel239 answer.
function goToSomeView(){
document.location.href = "{% url 'index' %}"
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/css/bootstrap.min.css" rel="stylesheet"/>
<p class="lead">Using 'a' element</p>
Create new recipe
<p class="lead mt-3">Using button</p>
<button onclick="goToSomeView()" class="btn btn-outline-secondary">Create new recipe</button>

got problem in the ajax form submission code

<form action="" method="post" class="f-color" id="email-form">
{% csrf_token %}
<label>Name</label>
<input type="text">
<label>From</label>
<input type="email">
<label>Message</label>
<button type="submit">Sent</button>
</form>
<div class="mt-5" id="spin" style="display: none;">
<div class="loader"></div>
</div>
<div id="msg"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(document).on("submit", "#email-form", function(event){
event.preventDefault();
$('#spin').show();
$.ajax({
url: "{% url 'contact' %}",
type: "POST",
data: $("#email-form").serialize(),
success: function(data){
$("#spin").hide();
if(data.status == "success"){
$("#msg").html("<p class='alert alert-success'>we will get back to you as soon as possible</p>" );
$("#email-form").reset();
}
}
})
})
})
</script>
using this code I can submit the form successfully, but after the form submission the message(msg) not showing, the 'if condition statement' is perfectly working (for the testing I gave the alert, the alert was worked)
another problem is form reset, for this I'm using
$("#email-form").reset();
but the form dose't reset
how can I solve these problems
try
$('#email-form')[0].reset();
https://stackoverflow.com/a/3786702/8640027
I got a solution for the resetting form after the ajax form submission
$("#email-form").trigger("reset");

Django print data of radio button?

I printed my data within the text box as
data = request.GET['information']
print(data)
in views.py
<form class="homepage" action = "{% url 'count' %}" >
<textarea name="information" rows="8" cols="80"></textarea>
<input type="submit" name="" value="Wordecounter">
</form>
It is returning the text from the text box but the question is if I used radio button and selected radio button on my browser then how could I print which option I selected in radiobutton from views.py
You would do exactly the same, so:
data = request.GET['information_radio']
print(data)
And your html:
<form class="homepage" action = "{% url 'count' %}" >
<input type="radio" name="information_radio" value="yes">Yes<br>
<input type="radio" name="information_radio" value="no">No<br>
<input type="submit" name="" value="Wordecounter">
</form>

Send JSON from Places Autocomplete to Flask

I'm working on my very first web app utilizing the Google Places Autocomplete functionality in the frontend and Flask in the backend.
Current situation:
Whenever an address is selected from the autocomplete suggestions, a variable called 'address' is populated in the background containing the API response as JSON. Using a window alert I can confirm that this part works fine.
To-Do/ issue:
The address variable should be sent over to Flask so that I can do use it going forward.
Using AJAX to post the data however it never seems to reach Flask. The output is always None.
My best guess is that the submit button implemented after the Autocomplete stuff somehow overrides the JSON POST data in order to keep only the actual text which is in the form while submitting*.
Does that make sense? If yes, how can I still send the JSON data successfully? Or is the issue somewhere else?
I would appreciate any help.
Here is my code:
home.html
{% extends "base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
{% from "_formhelpers.html" import render_field %}
<div class="container">
<form class="form form-horizontal" action="" method="post" role="form" novalidate>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=key&libraries=places&language=en"></script>
<script type="text/javascript">
google.maps.event.addDomListener(window, 'load', function () {
var autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'),{
types: ['geocode']
});
// autocomplete.setFields('address_components');
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
var address = place.address_components;
window.alert(JSON.stringify(address));
}
)})
$.ajax({
type: "POST",
url: "/",
data: address,
success: function(){},
dataType: "json",
contentType : "application/json"
});
</script>
<input type="text" id="autocomplete" size=50 style="width: 250px" placeholder="Enter your location" name=inputkiez>
<a href=# id=autocomplete><button class='btn btn-default'>Submit</button></a>
</form>
<div class="row">
or check out <a href='/result'> the latest reviews from others </a>
<div>
</div>
{% endblock %}
routes.py
#app.route('/', methods=['GET','POST'])
def search():
if request.method == 'POST':
jsdata = request.get_json()
flash('Data is: {}'.format(jsdata))
return redirect('/review')
return render_template('home.html')
#app.route('/review', methods=['GET', 'POST'])
def review():
reviewform = ReviewForm()
if reviewform.validate_on_submit():
userreview = Reviews(
reviewcriteria1= reviewform.reviewcriteria1.data,
reviewcriteria2= reviewform.reviewcriteria2.data,
reviewcriteria3= reviewform.reviewcriteria3.data,
)
db.session.add(userreview)
db.session.commit()
return redirect('/result')
return render_template('review.html', form=reviewform)
*The text in the form would include the address selected from Autocomplete but without any additional data obviously. I even managed to pass this text to the next page with request.form.to_dict() but this is not good enough for my use case since I also want at least the postal code to be sent over.
This is not the exact answer to my question but I found a way to send over the data to flask without having to bring in JSON/AJAX at all.
The trick is to send the data from the Autoplaces response as a hidden input of the form:
<form method="post" action="">
<input id="userinput" placeholder="Enter a location" type="text" name="name" class="form-control"><br>
<div id="map" style="height: 300px;width: 300px; float: none; margin: 0 auto;"></div><br>
<input type="hidden" name="address" id="address">
<input type="submit" name="submit" value="Submit" class="form-control btn btn-primary">
<div>or check out <a href='/result'> the latest reviews from others </a></div>
</form>
Then in routes.py you can easily get the data like this:
#app.route('/', methods=['GET','POST'])
def search():
if request.method == 'POST':
address = request.form['address']
# do something
This is basically a slightly modified version of the solution posted here (YT video).

Django passing parameters to views and templates

I got a navigation tree that tells me where i am on my website to build that navigation tree i always need to pass all variables from template to the view as <input type="hidden">. Then i need to pass it from the view to the next template and it goes on and on feels like a bad solution to pass the variables from every template to every view. so my question is if there is a better solution to my problem here is a screen of the navigation tree.
template:
<form action="{% url 'aktentabelle' %}" method="post" style="display:inline-block">
{% csrf_token %}
<input type="hidden" name="mitglied" value="{{Container.containernr}}" />
<input type="hidden" name="contpk" value="{{Container.pk}}" />
<input type="hidden" name="projectnr" value="{{projectnr}}" />
<input type="hidden" name="status" value="{{Container.status}}" />
<input type="hidden" name="chargepk" value="{{chargepk}}" />
<input type="hidden" name="chargenr" value="{{chargenr}}" />
<input class="btn btn-primary" type="submit" value="anzeigen" />
</form>
so in my templates i always need to pass alot of variables as hidden and in my view i need to convert them back to read them:
views.py:
def aktentabelle(request):
assert isinstance(request, HttpRequest)
container = request.POST['mitglied']
z = AkteForm
projectnr = request.POST['projectnr']
chargepk = request.POST['chargepk']
chargenr = request.POST['chargenr']
contpk = request.POST['contpk']
closecontainerform = CloseContainerForm
akte_list = Akte.objects.filter(container__containernr=container)
Anzahl_Akten =Akte.objects.filter(container__containernr=container).count
status = request.POST['status']
return render(
request,
'app/aktentabelle.html',
{
'title':'About',
'akte_list':akte_list,
'anzahl':Anzahl_Akten,
'container':container,
'aktenform':z,
'status':status,
'closecontainerform': closecontainerform,
'date':datetime.now().date,
'contpk':contpk,
'chargepk':chargepk,
'chargenr':chargenr,
'projectnr':projectnr,
}
)
as you can see i use so many lines to just pass all the variables from one template to a view and back to the template again just to build that navigation tree.
One way to do this would be to use filters. Something like below.
from django.template import Library
register = Library()
def get_fields(requested_key):
my_dict={
'title':'About',
'akte_list':akte_list,
'anzahl':Anzahl_Akten,
'container':container,
'aktenform':z,
'status':status,
'closecontainerform': closecontainerform,
'date':datetime.now().date,
'contpk':contpk,
'chargepk':chargepk,
'chargenr':chargenr,
'projectnr':projectnr,
}
return mydict.get("requested_key","")
register.filter('get_fields', get_fields)
Store this in template tags directory with a filename and in your template load this at the top using
{% load filename %}.
Then you can do something like below in your template.
{% load templatefilename %}
<form action="{% url 'aktentabelle' %}" method="post" style="display:inline-block">
{% csrf_token %}
<input type="hidden" name="mitglied" value="{{get_fields|containernr}}"
</form>