Our app POSTS user data and then get's a success or rejected response. The success response will come with a URL like such:
b'SUCCESS|http://examplesite.com/m.cfm?t=17&wm_login=info&gouser=50105E5C440'
The issue is when I split this data in python to so I can send users to the URL python encodes this URL so it no longer works.
There is no server error message but rather the error is apparent in the redirect URL:
http://examplesite.com/m.cfm?t=17&wm_login=info&gouser=50105E5C440
Notice the & gets converted to &
I have tried contless solution to similar problems but nothing seems to redirect the user to an uncoded URL. The part that get's me is that when I print() the redirect URL it actually shows the right one!
The reason I redirect to a page first is that this form is an iframe and otherwise the Parent page does not get redirected.
views.py
def iframe1(request):
ip = get_real_ip(request)
created = timezone.now()
if request.method == 'POST':
form = LeadCaptureForm1(request.POST)
if form.is_valid():
# Save lead
lead = form.save(commit=False)
lead.created = created
lead.birth_date = form.cleaned_data.get('birth_date')
lead.ipaddress = get_real_ip(request)
lead.joinmethod = "Iframe1"
lead.save()
# API POST and save return message
payload = {
...
}
r = requests.post(url, payload)
print(r.status_code)
print(r.content)
api_status1 = r.content.decode("utf-8").split('|')[0]
api_command1 = r.content.decode("utf-8").split('|')[1]
print(api_status1)
print(api_command1)
#backup_link = "https://govice.online/click?offer_id=192&affiliate_id=7&sub_id1=API_Backup-Link"
backup_link = "http://viceoffers.com"
lead.xmeets = r.content
lead.save()
# Redirect lead to Success URL
if "http" in api_command1:
return TemplateResponse(request, 'leadwrench/redirect_template.html', {'redirect_url': api_command1, 'api_status1': api_status1})
else:
return TemplateResponse(request, 'leadwrench/redirect_template.html', {'redirect_url': backup_link})
redirect_template.html
<html>
<head>
<meta http-equiv="refresh" content="5; url={{ redirect_url }}" />
<script>
window.top.location.href = '{{ redirect_url }}';
</script>
</head>
<body>
<p>api_status1: {{ redirect_url }}</p>
<p>api_command1: {{ api_command1 }}</p>
</body>
</html>
By default, Django will do HTML escaping of template arguments, which (among other things) changes & to &. Use the safe template filter in your template to avoid that:
<html>
<head>
<meta http-equiv="refresh" content="5; url={{ redirect_url|safe }}" />
<script>
window.top.location.href = '{{ redirect_url|safe }}';
</script>
</head>
<body>
<p>api_status1: {{ redirect_url }}</p>
<p>api_command1: {{ api_command1 }}</p>
</body>
</html>
Related
If i post values that values are saved in database, in case values duplicate it display the message like values can not duplicate by rendering html page.in my case values are stored in database but if enter any duplicate values it is throwing the error. how to display message if enter any duplicate values. is there any method method in views.py file
1062, "Duplicate entry 'django_post' for key 'title'"
Here models.py code
class Post(models.Model):
title= models.CharField(max_length=100, unique=True)
content= models.TextField()
view.py file
def createpost(request):
if request.method == 'POST':
if request.POST.get('title') and request.POST.get('content'):
post = Post()
post.title = request.POST.get('title')
post.content = request.POST.get('content')
post.save()
return render(request, 'emp.html')
emp.html file
<html lang="en">
<head>
<title>Create a Post </title>
</head>
<body>
<h1>Create a Post </h1>
<form action=" " method="POST">
{% csrf_token %}
Title: <input type="text" name="title"/><br/>
Content: <br/>
<textarea cols="35" rows="8" name="content">
</textarea><br/>
<input type="submit" value="Post"/>
</form>
</body>
</html>
Here is the html file I want to give the html page after posting the data through html page
duplicate.html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Duplicate values are entered</h1>
</body>
</html>
You can render the inserted.html after successfully saving the data in database. For this, you can change your view createpost as:
def createpost(request):
if request.method == 'POST':
if request.POST.get('title') and request.POST.get('content'):
post = Post()
post.title = request.POST.get('title')
post.content = request.POST.get('content')
post.save()
return render(request, 'inserted.html')
return render(request, 'emp.html')
use below line to redirect to any address you like,
return HttpResponseRedirect("https://www.another-url.com")
you need to import from django.http import HttpResponseRedirect
You should change HTML page:
Replace your code:
return render(request, 'emp.html')
To:
return render(request, 'inserted.html')
Or
add return statement inside:
if request.POST.get('title') and request.POST.get('content'):
......
return render(request, 'inserted.html')
models.py
class Post(models.Model):
title= models.CharField(max_length=100, unique=True)
content= models.TextField()
As you define the title must be unique, so you need to handle the duplicate exception and display an error message on UI side.
view.py
write your save post code inside try except block like:
try:
post = Post()
post.title = request.POST.get('title')
post.content = request.POST.get('content')
post.save()
except IntegrityError as e:
# add your error message
this link will help you how to add and display an error message.
I have below views.py file
from django.shortcuts import render, redirect, render_to_response
from bs4 import BeautifulSoup as bs
import time
output = []
def register(request):
output = get_form_data(request)
if output == None:
output=""
if request.POST.get('cancel'):
return redirect('/login/')
if output == 'Registration Successful':
t_end = time.time() + 5 * 1
while time.time() < t_end:
a = 0
return redirect('/login/')
return render(request, 'template/register.html', {"output": output})
def get_form_data(request):
if request.POST:
if request.POST.get('register'):
reg_uname = request.POST.get('reg_una')
reg_pass = request.POST.get('password')
reg_cnfpass = request.POST.get('cnfpass')
reg_email = request.POST.get('emailid')
return "Registration Successful"
I want to show the output "Registration Successful" when i click on register button before return render to the register.html page and then want 5 seconds to redirect the page to login page.
Currently if the registration is successful, after 5 seconds, I am redirected to the login page but I am unable see the "Registration Successful" message since I am not on the same page.
Below is the register.html file for reference
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Register</title>
<link href="/static/register.css" type="text/css" rel="stylesheet">
<script type="text/javascript">
function validate()
{
var name,pass,cnfpass,email;
name = document.getElementById("reg_uname");
pass = document.getElementById('reg_pass');
cnfpass = document.getElementById('reg_cnfpass');
email = document.getElementById('reg_email');
if(name.value == '')
{
alert('Username Cannot be left blank!');
name.focus();
return false;
}
else if(name.value.length < 3){
alert('Username cannot be less than 4 characters!');
name.focus();
return false;
}
if(pass.value != '' || cnfpass.value != '')
{
if(pass.value != cnfpass.value)
{
alert('Passwords should match!');
pass.focus();
return false
}
else if(pass.value.length <8)
{
alert('Password cannot be less than 8 characters!');
pass.focus();
return false;
}
}
else
{
alert('Please fill the password fields!');
pass.focus();
return false;
}
if(email.value == '')
{
alert('Please enter your email ID!');
email.focus();
return false;
}
return true;
}
</script>
</head>
<body>
<form action="" method="post" name="reg_form">
{% csrf_token %}
<div id="main">
<div id="main-register-image"></div>
<div id="main-register-box">
<div id="main-register-box-uname">
<div>Username :</div>
<div><input type="text" id="reg_uname" name="reg_una" value="" ></div>
</div>
<div id="main-register-box-pass">
<div>Password :</div>
<div><input type="password" id="reg_pass" name="password" value="" ></div>
</div>
<div id="main-register-box-cnfpass">
<div>Confirm Password :</div>
<div><input type="password" id="reg_cnfpass" name="cnfpass" value="" ></div>
</div>
<div id="main-register-box-email">
<div>Email ID :</div>
<div><input type="email" id="reg_email" name="emailid" value="" ></div>
</div>
<div id="main-register-box-buttons">
<div><input type="submit" id="reg" value="Resister" name="register" onclick="return validate()" /></div>
<div><input type="submit" id="cancel" name="canc" value="Cancel" onclick="/login/" /></div>
</div>
<div id="result">{{output}}</div>
</div>
</div>
</form>
</body>
</html>
My question is, how can we show dynamic data on html page and continue doing other stuffs on the same page.
You have to perform the request asynchronously in order to continue on the same page (AJAX). It is a fairly easy procedure, here's a guide for Django that might help you get started.
Essentially, you will have JavaScript send your request and process the response. You can send different messages depending on whether the request was successful or not, and inform the user.
Also, is there any specific purpose to the 5-second interval? You are doing busy waiting there (use sleep instead if necessary, or move that waiting to the frontent, using setTimeout).
So you want to display a message before the redirect. You have at least two ways of doing this:
Use an AJAX request to make the call to register, return a success/failure response. This will make the call completely javascript, with verification being done on the server side.
You pass the success parameter to the redirected page and (assuming you use Jinja2 or Django templating engine) you display a message if the registration was a success.
Also a few things about the views:
Do null checks with is: if output is None, instead of ==.
You're not don't seem to be doing anything with the form values, only getting them from the POST. Perhaps we just can't see the code though.
There's a variable output at the top of the module, and you also have a variable output in the register method. Consider not reusing the same variable name to prevent confusing situations.
If you want to wait for a few seconds, consider using sleep:
import time
time.sleep(t)
Where t is the amount of seconds to sleep.
You're checking if the output is None, and then later checking if the output matches a certain string. Perhaps you could put the final render in the first if statement:
as follows:
if output == None:
return render(request, 'template/register.html', {"output": ''})
The final result will look something like:
from django.shortcuts import render, redirect, render_to_response
from bs4 import BeautifulSoup as bs
import time
output = []
def register(request):
message = ''
if request.method == 'POST'
if request.POST.get('cancel'):
return redirect('/login/')
# Remember, get_form_data returns boolean now.
reg = get_form_data(request)
if reg:
return redirect('/login/')
else:
output = 'Registration failed'
return render(request, 'template/register.html', {"output": message})
def get_form_data(request):
if request.POST.get('register'):
reg_uname = request.POST.get('reg_una')
reg_pass = request.POST.get('password')
reg_cnfpass = request.POST.get('cnfpass')
reg_email = request.POST.get('emailid')
# Some registration function is probably called here
# Perhaps return a boolean instead, if registration was OK:
return register(username=reg_uname, pass=reg_pass, cnfpass=reg_cnfpass, email=reg_email)
return False
With jQuery, the AJAX call could look something like code below. If you consider using the AJAX method, I advise you to change your register function to return some kind of JSON response and an appropriate response status code. Check out the djangorestframework if you plan to use more of these kinds of calls.
function register() {
data = {};
// Get the data from the form fields here: e.g.:
data['username'] = $('reg_uname').val();
$.ajax({
url: '/register',
method: 'POST',
data: data,
success: function(data, textStatus, xhr) {
// Handle success scenario here.
},
error: function(xhr, status, error) {
// Handle fail scenario here.
}
)};
}
As mentioned above you would need to use AJAX or instead you could just return an intermediary "Successful" page that redirects the user to the login page using Javascript. I would say this is the simplest way:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<p>Success!</p>
<script type="text/javascript">
window.onload = function() {
setTimeout(function(){
window.location = '/login'; // redirects to login page
}, 10000); // waits 10 seconds
};
</script>
</body>
</html>
I am trying to create a redirect when the user logs in. For example when user tries to access a link to create blog post he is prompted to log in , and after he gets logged in he is redirected to the page to create the post. I am extracting the next parameter from the url.
blog.urls
from django.conf.urls import url
from blog import views
urlpatterns=[
url(r'^$',views.index,name="index"),
url(r'^signup/$',views.signup_view,name="signup_view"),
url(r'^login/$',views.login_view,name="login_view"),
url(r'^create-post/$',views.create_blog,name="create_post"),
url(r'^logout/$',views.logout_view,name="logout_view"),
]
blog.views:
def login_view(request):
if request.method == 'POST':
form=LoginForm(request.POST)
if form.is_valid():
username=form.cleaned_data['username']
password=form.cleaned_data['password']
user=authenticate(username=username,password=password)
if user is not None:
if user.is_active:
login(request,user)
go_to=request.GET.get('next','/')
print go_to
return HttpResponseRedirect(go_to)
else:
return HttpResponse("Not active")
else:
return HttpResponse("User doesn't exist")
else:
form=LoginForm()
return render(request,'blog/login.html',{'form':form})
and blog/login.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form method="POST" action="/login/">
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<button type="submit">Submit</button>
</form>
</body>
</html>
Whenever I login it shows the next parameter as '/' while there is "next=/create-blog/" in the url. Please suggest any solution.
you need:
action="/login/{% if request.GET.next %}?next={{ request.GET.next }}{% endif %}"
If the value of {{ request.GET.next }} includes parameters, e.g. http://example.com/?var1=abc&var2=def, then use URL encoding {{ request.GET.net | urlencode }}.
The problem is after I get a request and I assign value to variable msg my template login.html is still empty and I want to see message = 'got it'.
app.py
from flask import Flask, render_template, redirect, url_for, request
app = Flask(__name__)
#app.route('/req', methods=['GET', 'POST'])
def req():
msg = None
if request.method == 'POST':
if request.values.get('name', None) == 'asdf':
msg = 'got it'
#print msg - variable msg = 'got it'
return render_template('login.html', msg=msg)
if __name__ == '__main__':
app.run(debug=True)
login.html
<html>
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="static/bootstrap.min.css" rel="stylesheet" media="screen">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
var test = function() {
$(function() {
$.ajax({
type: "POST",
url: "/req",
data: {'name': 'asdf'},
});
});
}
window.setInterval(function() {
test()
}, 5000);
</script>
</head>
<body>
{% if msg %}
{{ msg }} #empty page
{% endif %}
</div>
</body>
</html>
It looks like you're mixing up template rendering and Ajax.
Your JavaScript test function does call your req view method in the back-end, which does render a template, but you're not doing anything with that template.
Your msg variable that you're attempting to print in the template where you have your # empty page note will never be rendered, as there's no msg variable that isn't None at the time the base template is rendered. msg is set by the POSTing via Ajax, but that rendered template is never displayed.
If your goal is to just see the msg output on the page, have your req method just return that on a POST:
#app.route('/req', methods=['GET', 'POST'])
def req():
msg = None
if request.method == 'POST':
if request.values.get('name', None) == 'asdf':
return 'got it'
return render_template('login.html', msg=msg)
And in your Ajax call,
var test = function() {
$(function() {
$.ajax({
type: "POST",
url: "/req",
data: {'name': 'asdf'},
success: function(data) {
// do something with your 'got it' string
}
});
});
}
If you really want to return your template as you have it written in the question, you're much better off with a form to submit instead of Ajax so you'll browse to the new page:
#app.route('/req', methods=['GET', 'POST'])
def req():
msg = None
if request.method == 'POST':
if request.values.get('name', None) == 'asdf':
render_template('login.html', msg=msg)
return render_template('login.html', msg=None)
And the HTML:
<html>
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="static/bootstrap.min.css" rel="stylesheet" media="screen">
</head>
<body>
<form action="/req" method="POST">
<input type="text" name="name">
<input type="submit" value="Submit">
</form>
{% if msg %}
{{ msg }} #empty page
{% endif %}
</div>
</body>
</html>
When I open the html file it displays as expected and when I enter data in the text box and submit, It redirects me to localhost/myapp/output/ but why is the data I enter in the text box not submitted for example like localhost/myapp/output/data_I_submitted
My basic html file:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>db app</title>
</head>
<body>
{% csrf_token %}
<form action="output/" method="post" name="Input">
Data : <input type="text" name="text">
<input type="submit" value="submit">
</form>
</body>
</html>
In my app.urls file:
urlpatterns = patterns('',
url(r'^$',views.index),
url(r'^output/(?P<text>\w+)/$',views.return_data)
)
Finally the view:
def return_data(request,text):
return HttpResponse('entered text ' + text)
If your goal is only getting the text on the form:
change your view to
def return_data(request):
return HttpResponse('entered text:' + request.POST['text'])
edit your urls
urlpatterns = patterns('',
url(r'^$', views.index),
url(r'^output/$', views.return_data)
)
and your template
<form action="output/" method="post">
{% csrf_token %}
...
</form>
you'd better review data submitting in forms.
with two methods you can submit forms data with your request to the forms action attribute:
GET: like http://www.google.com/?q=keyword+to+search
you can access the "keyword+to+search" by:
request.GET['q']
#or better is:
request.GET.get('q', None)
the text arguement is not passed to url pattern. so not accessible in this way
POST:
in this method the data is not in request url.
so to access the forms data submittin by POST method
try this
request.POST['text'] (
#or better is:
request.POST.get('text', None)
but it is highly recommended to use Django forms instead of direct accessing from request.POST or request.GET
so check this: https://docs.djangoproject.com/en/dev/topics/forms/