Pass value from django view to same template - django

I am new to Django. I am trying to create a website with two input textboxes. When the submit button clicked, I need to update the results from django view to the same template without reloading the webpage.
Here is my code so far:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<H1>Welcome to Test</H1>
<div class="input-group" >
Input Text:<br>
<textarea class="form-control" rows="20" cols="70" name="InputText"
placeholder="Enter your Input Text here" form="myForm">
</textarea>
<span class="input-group-addon"><br></span>
Input TextFSM Template:<br>
<textarea class="form-control" rows="20" cols="70" name="InputTemplate"
placeholder="Enter your template here" form="myForm">
</textarea>
<form action="" method="post" id="myForm">
{% csrf_token %}
<input type="submit" value="Submit">
</form>
</div>
<div id="resultid">
<p>Result:</p>
{{result}}
</div>
</body>
</html>
views.py
class HomePageView(TemplateView):
template_name = "index.html"
def get(self, request, **kwargs):
form = ParserForm()
return render(request, self.template_name, {"form": form})
def post(self, request, **kwargs):
form = ParserForm(request.POST)
if form.is_valid():
inputtext = form['InputText'].value()
template = form['InputTemplate'].value()
# Process the data and get the result
print(result)
return render(request, self.template_name, {'result': result})
How to pass the result to index.html from view but the text entered in the textboxes should be persistent.

There is no direct way to update result in django templates or django views without reloading the page. In addition, once page in rendered you need second request to update that page. You could use jquery ajax to do fetch data from server without reloading page.
Ajax is asynchronous javascript extension which is use to send request with out reloading page. This would help you to do exactly that you want.
You could get more help from here
See following example for an instance.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
<body>
<H1>Welcome to Test</H1>
<div class="input-group" >
Input Text:<br>
<textarea class="form-control" rows="20" cols="70" name="InputText"
placeholder="Enter your Input Text here" form="myForm">
</textarea>
<span class="input-group-addon"><br></span>
Input TextFSM Template:<br>
<textarea class="form-control" rows="20" cols="70" name="InputTemplate"
placeholder="Enter your template here" form="myForm">
</textarea>
<form id="my-form" action="" method="post" id="myForm">
{% csrf_token %}
<input type="submit" value="Submit">
</form>
</div>
<div id="resultid">
<p>Result:</p>
{{result}}
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
(function($){
function processForm( e ){
$.ajax({
url: '/url-to-call/', //replace this with url that you want to hit without reloading the page
dataType: 'text',
type: 'post',
contentType: 'application/x-www-form-urlencoded',
data: $(this).serialize(),
success: function( data, textStatus, jQxhr ){
// manipulate stuff or action
},
error: function( jqXhr, textStatus, errorThrown ){
// This is executed when some error occures
}
});
e.preventDefault();
}
$('#my-form').submit( processForm );
})(jQuery);</body>
</html>

Related

Axios Post request Is Not Working it is Changing to get request

I Am trying To Send Post request to The Django using Axios But it Is Not Working
instead it sending get request after the submit button is pressed.
I don't know why this happening I Hvae configured Everything corretelty but it is not working
Any Has Any solution to this then please help me
My Html Code Is
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Out</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.1.3/axios.min.js" integrity="sha512-0qU9M9jfqPw6FKkPafM3gy2CBAvUWnYVOfNPDYKVuRTel1PrciTj+a9P3loJB+j0QmN2Y0JYQmkBBS8W+mbezg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
{% load static %}
</head>
<body>
<div align = "center">
<form action="" name = "out" id ="out" >
{% csrf_token %}
<table>
<th>Name</th>
<th>Stock_out</th>
<tr>
<td><input type="text" id="name" name="name"></td>
<td><input type="text" id="stock_out" name="stock_out"></td>
</tr>
<tr >
<td><span id ="name_er"></span></td>
<td><span id ="stock_err"></span></td>
</tr>
</table>
<input type="button" value="Submit" form = "out" onclick="submit()">
</form>
</div>
<script src="{% static 'out.js/'%}"></script>
</body>
</html>
Here Is My Js Script
function submit(){
let nam = document.getElementById('name').value;
let out = document.getElementById('stock_out').values
if(nam=="" | nam==null){
document.getElementById('nam-er').innerHTML="Name Insert please"
return false
}else{
let form = document.getElementById('out');
var data = new FormData(form);
data.append('name', document.getElementById('name').value);
data.append('stock_out', document.getElementById('stock_out').value);
data.append("csrfmiddelwaretoken",'{{csrf_token}}');
// form.reset();
axios.post('add/product_out',data).then(function(resp){
window.location.href = "add/success";
console.log(resp);
})
.catch(function (error) {
console.log(error);
})
}
}
Here Is My Django Views
def product_out(request):
if request.method =='POST':
name = request.POST.get('name')
stock = request.POST.get('stock_out')
Stock_Out.objects.create(
name=name,
stock_out=stock
)
resp = {
"status":'success'
}
return JsonResponse(resp)
urls.py
from django.urls import path
from add import views
urlpatterns =[
path('add',views.add, name='add'),
path('success',views.success, name='success'),
path('stock_out',views.stock_out, name = 'stock_out'),
path('product_out',views.product_out, name = 'product_out')
]
I Want Send The to The Server from input field Which is Shown on the picture that come from http response from the browser(https://i.stack.imgur.com/3FrMS.png)
I think the issue is that the browser's default submit is triggering making it skip all your javascript part. Try preventing it with preventDefault():
Pass the event to your js (note the e in the parenthesis)
<input type="button" value="Submit" form = "out" onclick="submit(e)">
Prevent the default behaviour:
function submit(e){
e.preventDefault()
// ..the rest of your script here
}
Alternatively, you could change the submit button from being a <input type="submit" /> to a <button type="button">Submit</button>

I want to get e-mail authentication

An authentication number function that generates eight random characters was implemented.
i inputted username, and mail. because i want to write searching password html and request it at view with Ajax.
When I enter my username and email, I want the authentication number to be sent to the email. At the same time, the code created in ajax should show the authentication number window.
but, it happened nothing.
what should i do...?
help me!
error is Uncaught SyntaxError: Unexpected token '<' WHAT'S THAT..?
First of all, I corrected the white page. I missed it. '>'
#html
{% load static %}
<!DOCTYPE html>
<html lang="KO">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="{% static 'users/css/recovery_pw.css' %}" rel="stylesheet">
<link href="{% static 'users/css/default.css' %}" rel="stylesheet">
<script
src="https://kit.fontawesome.com/96379a54a1.js"
crossorigin="anonymous"
></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="{% static 'users/js/recovery_pw.js' %}" </script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
{% block content %}
<form method="get" enctype="multipart/form-data">
<div class="container">
<div class="inner-box">
<div class="title">
<h1>비밀번호 찾기</h1>
</div>
<div class="input-box">
<div class="id">
<input type="email" placeholder="등록하신 메일로 인증번호가 발송됩니다." name="email" maxlenth="20" autocomplete="off" value="{{ form.email.value|default_if_none:'' }}" required />
</div>
<div class="password">
<input type="username" placeholder="아이디를 입력하세요" name="username" maxlength="20" value="{{ form.username.value|default_if_none:'' }}" required />
</div>
</div>
<div class="btn">
<div class="btn-white" id="btn_white"><button type="submit">임시 비밀번호 발송</button></div>
</div>
<div class="loading-box">
<div id="loading"></div>
</div>
</div>
</form>
{% endblock %}
</body>
</html>
#users/js/recovery_pw.js
$(document).ready(function () {
$('#find_pw').click(function () {
$('#loading').replaceWith('<div id="loading_end" class="loading"></div>')
// 걍 임의로 만든것 같음
var name = $("#pw_form_name").val();
var email = $("#pw_form_email").val();
$.ajax({
type: "POST",
url: "/users/recovery/pw/find/",
dataType: "json",
data: {
'name': name,
'email': email,
'csrfmiddlewaretoken': '{{csrf_token}}',
},
success: function (response) {
// loading_end 이걸 지움
$('#loading_end').remove()
alert('회원님의 이메일로 인증코드를 발송하였습니다.');
// 나는 이메일전송버튼이지
$('#btn_white').remove()
$('#result_pw').replaceWith(
'<hr><div class="row justify-content-md-center"><form class="form-inline" style="margin-bottom:-15px; margin-top:-10px;"><div class="md-form md-outline"><label for="input_auth_num">인증번호 입력 (<span id="timeset"></span>)</label><input type="text" id="input_auth_num" class="form-control mx-sm-2" autofocus/></div></form>' +
'<button type="submit" name="auth_confirm" id="id_auth_confirm" class="btn btn-red" style="opacity: 90%; height:30%; margin-top:10px; font-size: 12px;"><i class="fas fa-check"></i> 인증확인</button></div><hr>'
)
function countdown(elementName, minutes, seconds) {
var elementName, endTime, hours, mins, msLeft, time;
function twoDigits(n) {
return (n <= 9 ? "0" + n : n);
}
function updateTimer() {
msLeft = endTime - (+new Date);
if (msLeft < 1000) {
alert("인증시간이 초과되었습니다.");
$("" + elementName).remove();
cert_ok = false;
certificationNum = false;
location.href = "{% url 'recovery_pw' %}"
} else {
time = new Date(msLeft);
hours = time.getUTCHours();
mins = time.getUTCMinutes();
$("" + elementName).html((hours ? hours + ':' + twoDigits(mins) : twoDigits(mins))
+ ':' + twoDigits(time.getUTCSeconds()));
setTimeout(updateTimer, time.getUTCMilliseconds() + 500);
}
}
endTime = (+new Date) + 1000 * (60 * minutes + seconds) + 500;
updateTimer();
}
countdown("#timeset", 5, 0);
var user = response.result
$(document).ready(function () {
$('#id_auth_confirm').click(function () {
var input_auth_num = $("#input_auth_num").val();
$.ajax({
type: "POST",
url: "/users/recovery/pw/auth/",
dataType: "json",
data: {
'input_auth_num': input_auth_num,
'csrfmiddlewaretoken': '{{csrf_token}}',
},
success: function (response) {
location.href = "{% url 'recovery_pw_reset' %}";
},
error: function () {
if ($('#input_auth_num').val() == "") {
alert('회원님의 이메일로 전송된 인증번호를 입력해주세요.');
} else {
alert('인증번호가 일치하지 않습니다.');
}
},
});
})
})
},
error: function () {
$('#loading_end').remove()
if (username == "" || email == "") {
alert('이름, 이메일을 모두 입력해주세요.');
} else {
alert('입력하신 정보가 일치하지 않거나 존재하지 않습니다.');
}
},
});
})
});
#views.py
class RecoveryPwView(View):
template_name = 'users/recovery_pw.html'
recovery_pw = RecoveryPwForm
def get(self, request):
if request.method=='GET':
form = self.recovery_pw(None)
return render(request, self.template_name, { 'form':form, })
def ajax_find_pw_view(request):
username = request.POST.get('username')
email = request.POST.get('email')
target_user = User.objects.get(username=username, email=email)
if target_user:
auth_num = email_auth_num()
target_user.auth = auth_num
target_user.save()
send_mail(
'this is email verify',
['email'],
html=render_to_string('users/recovery_email.html', {
'auth_num': auth_num,
}),
)
return HttpResponse(json.dumps({"result": target_user.username}, cls=DjangoJSONEncoder), content_type = "application/json")
#urls.py
path('recovery/pw/', RecoveryPwView.as_view(), name='recovery_pw'),
path('recovery/pw/find/', views.ajax_find_pw_view, name='ajax_pw'),
path('recovery/pw/auth/', views.auth_confirm_view, name='recovery_auth'),
path('recovery/pw/reset/', views.auth_pw_reset_view, name='recovery_pw_reset'),
form
class RecoveryPwForm(forms.Form):
username = forms.CharField(label='id')
email = forms.EmailField(label='email')
class Meta:
fields = ['username', 'email']
class CustomSetPasswordForm(forms.Form):
new_password = forms.CharField(
max_length=16,
min_length=6,
label=_('새 비밀번호')
)
confirm_password = forms.CharField(
max_length=16,
min_length=6,
label=_('새 비밀번호 확인')
)
since you are using the get method into the View model, you can use it directly without checking by method and that is what that function does for ease
Note:-
now you handle the request method by get method which you can't use csrf_token into your form
now the problem is that, you are trying to use get method to send data then, you want to get this data in ajax by Post method which you won't receive any data of course in addition to, that you are trying to execute the separate function in the view which cause a problem where the function will never execute because the form doesn't know where should it send the data in after the request is created.
so, now you can remove the additional function you use and try to use and include what you want in the one view to prevent the confusion so, follow the solution like so:
class RecoveryPwView(View):
template_name = 'users/recovery_pw.html'
recovery_pw = RecoveryPwForm
def get(self, request):
form = self.recovery_pw(None)
return render(request, self.template_name, { 'form':form})
def post(self, request):
form = self.recovery_pw(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
email = form.cleaned_data.get('email')
target_user = User.objects.get(username=username, email=email)
# do send email here
# return the render that you want to finish by post method here
html
<form method="post">
{% csrf_token %}
<div class="container">
<div class="inner-box">
<div class="title">
<h1>비밀번호 찾기</h1>
</div>
<div class="input-box">
{% comment %} <div class="id">
<input type="email" placeholder="등록하신 메일로 인증번호가 발송됩니다." name="email" maxlenth="20" autocomplete="off" value="{{ form.email.value|default_if_none:'' }}" required />
</div>
<div class="username">
<input type="username" placeholder="아이디를 입력하세요" name="username" maxlength="20" value="{{ form.username.value|default_if_none:'' }}" required />
</div> {% endcomment %}
{% for field in form %}
<label>{{ field.label }}</label>
<div>{{ field }}</div>
{% endfor %}
</div>
<div class="btn">
<div class="btn-white" id="btn_white"><button type="submit">임시 비밀번호 발송</button></div>
</div>
<div class="loading-box">
<div id="loading"></div>
</div>
</div>
</form>
Now this solution is not completed, because I'm not sure from understanding exactly what you want to do but at least you can see that there's something new happen for your problem to find the min problem, the issue now will come from Ajax just let me know what you are facing after that

how to create a function update using django and ajax

i have a django project that include a form where user insert data and save it into database using django function and ajax call.
without using the ModelForm in django.
now i want to allow the user to update the form that he choose and once the user choose the form the fields must be displaying the existing data.
until now this was the create process.
i know that the update process will need the id of the object in order to be able to update the selected record.
the error :
'suspect' object is not iterable Request Method: GET Request
URL: http://127.0.0.1:8000/blog/update/23/ Django Version: 2.1.3
Exception Type: TypeError Exception Value: 'suspect' object is not
iterable Exception Location: C:\Users\LT
GM\AppData\Local\Programs\Python\Python37\lib\site-packages\django\template\defaulttags.py
in render, line 165 Python Executable: C:\Users\LT
GM\AppData\Local\Programs\Python\Python37\python.exe
urls.py
path('update/<int:pk>/',update,name = 'update'),
update.html
{% extends "base.html" %}
{% load static %}
{% block body %}
<head>
<link rel="stylesheet" type="text/css" href="{% static '/css/linesAnimation.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/input-lineBorderBlue.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/dropDown.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/home.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/meta-Input.css' %}">
<meta name= "viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="{% static '/js/jquery-3.1.1.min.js'%}"></script>
<title>Welcome</title>
</head>
<body>
<div class="lines">
<div class="line"></div><div class="line"></div>
<div class="line"></div><div class="line"></div>
<div class="line"></div><div class="line"></div><div class="line"></div>
</div>
{% for suspect in instance %}
<form enctype="multipart/form-data">
<div id='left-column-Input' class="formInput" include="select()">
<div class="forminputs">
<input type="text" id="fname" name="fname" autocomplete="off" required />
<label for="fname" class="label-name">
<span class="content-name" name="fname">{{suspect.suspect_name}}</span>
</label>
</div>
<div class="forminputs">
<input type="text" id="lname" name="lname" autocomplete="off" required />
<label for="lname" class="label-name">
<span class="content-name" name="lname">{{suspect.suspect_last_name}}</span>
</label></div>
<div class="forminputs">
<input type="text" id="fatherName" name="fatherName" autocomplete="off" required />
<label for="fatherName" class="label-name">
<span class="content-name" name="fatherName">{{suspect.suspect_father_name}}</span>
</label></div>
<div class="forminputs">
<input type="text" id="motherName" name="motherName" autocomplete="off" required />
<label for="motherName" class="label-name">
<span class="content-name" name="motherName">{{suspect.suspect_mother_name}}</span>
</label></div>
<div class="formSelect">
<select id="gender" name="gender" required>
<option value="">{{suspect.gender}}</option>
<option value="1">male</option>
<option value="2">female</option>
</select></div>
<div>
<textarea id="content" name="textarea" class="textArea" placeholder="content">{{suspect.content}} </textarea>
</div>
<div class="home-Button">
<button id="edit" name="edit" type="submit">Edit</button>
<button id="clear" name="clear" type="submit">Clear</button>
</div>
</div>
{% endfor %}
<script type="text/javascript">
$(document).ready(function(){
$("#edit").on('click',function(event){
event.preventDefault()
fName=$('#fname').val()
lName = $('#lname').val()
fatherName = $('#fatherName').val()
motherName = $('#motherName').val()
gender = $('#gender').val()
content=$('#content').val()
$.ajax({
url:'/blog/update',
method:'POST',
data: {
FName: fName,
LName: lName,
FatherName: fatherName,
MotherName: motherName,
Gender: gender,
content:content,
// data:data
},
headers:{
'X-CSRFToken':'{{csrf_token}}'
}
}).done(function(msg){
location.href='/blog/list'
}).fail(function(err){
alert(err)
})
})
})
</script>
</form>
</body>
{% endblock %}
views.py
def update(request,pk):
#deny anonymouse user to enter the detail page
if not request.user.is_authenticated:
return redirect("login")
else:
suspect = get_object_or_404(suspect, pk=pk)
if request.method =="POST":
suspect = suspect()
suspect.suspect_name = request.POST['FName']
suspect.suspect_last_name = request.POST['LName']
suspect.suspect_father_name = request.POST['FatherName']
suspect.suspect_mother_name = request.POST['MotherName']
suspect.gender = request.POST['Gender']
suspect.content = request.POST['content']
print(suspect.suspect_name)
suspect.save()
context = {
"title":member.member_name,
"instance":member,
}
return render(request,'blog/update.html',context)
i will appreciate any help
I will give you a simple example that you can extend for your case.
In the template where the user have a link to update his profile :
Update Profile
in your urls.py
path('update_profile/', views.ProfileUpdate, name='Profile-Update')
in views.py
def ProfileUpdate(request):
current_user = request.user
if request.method == 'POST':
get_username = request.POST.get('username', '').strip()
suspect.objects.filter(pk=current_user.pk).update(username=get_username)
return HttpResponse('Profile Updated')
else:
return render(request, 'prorile_update_form.html', {'current_user': current_user})
in prorile_update_form.html :
<form class="update_profile">
{{ csrf_token }}
<input type="text" name="username" value="{{ current_user.username }}">
<button class="submit_update">Save changes</button>
</form>
<!-- So the current user username will be displayed on the input as a value -->
<script type="text/javascript">
$('.submit_update').on('click', function(){
$.ajax({
url: '/update_profile/',
method : 'POST',
data: $('.update_profile').serialize(),
beforeSend: function() {
// things to do before submit
},
success: function(response) {
alert(response)
}
});
return false;
});
</script>
If the user have a different model that he can update so you may want to pass the id of the form as a variable in the url like this :
path('update_profile/<int:pk>', views.ProfileUpdate, name='Profile-Update')
And you interpret the variable on your view like this :
def ProfileUpdate(request, pk):
you can use the pk to fetch the required model and than make all the required updates based on the form that you will provide.

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 unit testing: assertEqual() fails

I am following the book "Test-Driven Development in Python" and have the following functions:
tests.py:
def testHomePageCanSaveAPostRequest(self):
request = HttpRequest()
request.method = 'POST'
request.POST['itemText'] = 'A new list item'
response = homePage(request)
if response:
response = response.content.decode('UTF-8')
self.assertIn('A new list item', response)
expectedHTML = render(request, 'lists/home.html', {'itemText':'A new list item'})
if expectedHTML:
expectedHTML = expectedHTML.content.decode('UTF-8')
print(response)
print(expectedHTML)
if response==expectedHTML:
print('Same')
self.assertIn('A new list item', expectedHTML)
self.assertEqual(response, expectedHTML)
views.py
def homePage(request):
print(request.POST.get('itemText'))
return render(request, 'lists/home.html', {'itemText':request.POST.get('itemText')})
home.html:
...
<form method=POST>
<input id=newItem name=itemText placeholder="Enter a to-do item">
</form>
<table id=listTable>
<tr><td>{{itemText}}</td></tr>
</table>
...
Both assertIn(..., response) and assertIn(..., expectedHTML) are successful, which means both response and expectedHTML have 'A new list item' in them.
I also print out response and expectedHMTL, and they look exactly the same. The comparison also print out 'Same' showing that they are the same.
However, the assertEqual fails with the following line by line comparison:
...
<table id=listTable>
- <tr><td>None</td></tr>
? ----
+ <tr><td></td></tr>
</table>
...
One is None and the other is empty.? What did I do wrong?
EDIT:
The entire test output is listed in the following:
Creating test database for alias 'default'...
A new list item
<!doctype html>
<html>
<head>
<title>To do list</title>
<meta charset=utf-8>
</head>
<body>
<h1>Your to do list</h1>
<form method=POST>
<input id=newItem name=itemText placeholder="Enter a to-do item">
</form>
<table id=listTable>
<tr><td>A new list item</td></tr>
</table>
</body>
</html>
<!doctype html>
<html>
<head>
<title>To do list</title>
<meta charset=utf-8>
</head>
<body>
<h1>Your to do list</h1>
<form method=POST>
<input id=newItem name=itemText placeholder="Enter a to-do item">
</form>
<table id=listTable>
<tr><td>A new list item</td></tr>
</table>
</body>
</html>
Same
.None
F.
======================================================================
FAIL: testHomePageReturnsCorrectHTML (lists.tests.HomePageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/yltang/course/TDD/lecture/python/webapps/git/superlists/superlists/lists/tests.py", line 27, in testHomePageReturnsCorrectHTML
self.assertEqual(response, expectedHTML)
AssertionError: '<!do[231 chars]stTable>\n <tr><td>None</td></tr>\n</table>\n</body>\n</html>' != '<!do[231 chars]stTable>\n <tr><td></td></tr>\n</table>\n</body>\n</html>'
<!doctype html>
<html>
<head>
<title>To do list</title>
<meta charset=utf-8>
</head>
<body>
<h1>Your to do list</h1>
<form method=POST>
<input id=newItem name=itemText placeholder="Enter a to-do item">
</form>
<table id=listTable>
- <tr><td>None</td></tr>
? ----
+ <tr><td></td></tr>
</table>
</body>
</html>
----------------------------------------------------------------------
Ran 3 tests in 0.017s
FAILED (failures=1)
Destroying test database for alias 'default'...
You have added the print statements to a different test. The print statements are in testHomePageCanSaveAPostRequest, which is passing.
The failing test is testHomePageReturnsCorrectHTML, which you have not included in your question.