I'm attempting to submit my form, but it continually fails as there's something wrong with the POST. I'm unsure where/what exactly is causing the server to not process the request whether it's related to syntax, request routing, etc. I've also commented out every line related to file uploads, as well as comment out the if (validated) statement. There are no errors in the console as a result of this, but the form submission still fails. I'd appreciate any help/direction thanks.
I get this error message when I submit the form:
POST http://127.0.0.1:5051/register/ 400 (BAD REQUEST)
views.py
#blueprint.route("register/", methods=['GET', 'POST'])
def register():
"""Renders register page."""
form = RegisterForm()
if request.method == 'POST':
if not form.validate_on_submit():
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=False, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
ticket, err = create_ticket2(customer_id, organization + "\n" + venue_name + "\n" + street + "\n" + country + "\n" + teamviewquestion + "\n" + teamviewerid + "\n" + deviations + "\n" + deviationsnotes + "\n" + displaydirector + "\n" + composer + "\n" + decryptor + "\n" + motionrocket + "\n" + othersoftware,
location=location)
if err:
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=False, message=err, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
else:
success_msg = "Error"
.format(ticket.get('id'))
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=True, message=success_msg, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
return render_template('main/register.html', page_title="Service Registration",
form=form, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
"""Handles file upload POSTs."""
first_name = request.form.get("first_name")
last_name = request.form.get("last_name")
name = request.form.get("first_name") + " " + request.form.get("last_name")
email = request.form.get("email")
filename = request.form.get("filename")
file_type = request.form.get("file_type")
if filename == '':
response = make_response("No selected file")
return response, 400
if check_file_type(file_type):
filename = clean_filename(filename)
filename = secure_filename(filename)
filename = unique_filename(filename)
response = generate_presigned_post(filename, file_type)
# CREATE DB REFERENCE
url = "http://nevcodocs.s3.amazonaws.com/Uploads/{}".format(filename)
instance = CustomerFileUpload.query.filter_by(url=url).first()
if not instance:
instance = CustomerFileUpload(url=url, email=email, name=name)
db.session.add(instance)
db.session.commit()
else:
instance.update(created_at=datetime.utcnow())
return response, 200
js (ticket submission function)
$('#ticket-form').submit(function(event) {
if (validated) {
$('#filename').val($('#upload').val());
$.ajax({
type: 'POST',
url: '/register/',
data: $('#ticket-form').serialize()
}).done(function(data) {
var formData = new FormData();
for (var key in data.data) {
formData.append(key, data.data[key]);
}
formData.append('file', $('#upload').prop('files')[0]);
formData.append('csrf_token', '{{ csrf_token }}');
var req = new XMLHttpRequest();
req.onload = function() {
showSpinner(false);
$('#ticket-form').removeClass("support-form-show");
$('#ticket-form').addClass("support-form-hide");
};
req.onerror = function() {
showSpinner(false);
$('#ticket-form-failed').removeClass("support-form-hide");
$('#ticket-form-failed').addClass("support-form-show");
};
req.open('POST', '/register/');
req.send(formData);
}).fail(function(err) {
showSpinner(false);
$('#ticket-form-failed').removeClass("support-form-hide");
$('#ticket-form-failed').addClass("support-form-show");
});
} else {
showSpinner(false);
enableSubmit(true);
}
});
Usually, bad request means that you're trying to fetch data from request object using invalid keys. So you need to make sure that your POST request body (that was sent by javascript) contains all keys which you're using as arguments of request.form.get() method: first_name, last_name, etc...
Related
I would like to write an api with django rest framework, I got some issues with my callback function.
I can get the access code, but how to give it to my app?
This is my callback function :
#api_view(['GET'])
def callback(request):
if request.method == 'GET':
code = request.GET.get("code")
encoded_credentials = base64.b64encode(envi.SECRET_ID.encode() + b':' + envi.SECRET_PASS.encode()).decode("utf-8")
token_headers = {
"Authorization": "Basic " + encoded_credentials,
"Content-Type": "application/x-www-form-urlencoded"
}
token_data = {
"grant_type": "authorization_code",
"code": code,
"redirect_uri": "http://127.0.0.1:800/callback"
}
test = "test :" + code
return JsonResponse(test, safe=False)
And this is my view where I try to do some stuff (I use spotify's API, with spotipy), I need to get the users name or mail :
#api_view(['GET'])
#permission_classes([permissions.IsAuthenticated])
def test(request):
if request.method == 'GET':
test = "test " + request.user.username
scope = "user-read-private"
sp = getScope(scope)
print(sp.current_user())
urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=envi.SECRET_ID, client_secret=envi.SECRET_PASS, redirect_uri=envi.SPOTIPY_REDIRECT_URI))
artist = sp.artist(urn)
print(artist)
user = sp.current_user()
return JsonResponse(user, safe=False)
def getScope(spotipyScope):
token = SpotifyOAuth(scope=spotipyScope,client_id=envi.SECRET_ID, client_secret=envi.SECRET_PASS, redirect_uri=envi.SPOTIPY_REDIRECT_URI)
spotifyObject = spotipy.Spotify(auth_manager= token)
return spotifyObject
When I do a get on 127.0.0.1:8000/test/, I have a new page on my browser, from spotify, I connect my account, and then, it redirects me on 127.0.0.1:8000/callback/?code=some_code
How can I give it to my first page waiting for the code so I can print the users stuff pls?
I'm setting a new server in Flask for an API. And a server to render the frontend in Flask also. Ok, so when i make a request to a determine API route i get this strange response 'This page was not found'. I it really seems to be every thing ok how can i debug this bug? Other Strange thing is that it allways give me status 200 OK. The error is in the route: #app.route('/v1.0/aluno/update/', methods=['POST'])
API SIDE
#app.route('/v1.0/aluno/<int:aluno_id>', methods=['GET'])
def aluno(aluno_id):
if request.method == 'GET':
cur = mysql.connection.cursor()
query = "SELECT NOME, NUMERO, PASSWORD FROM aluno WHERE NUMERO=%s"
cur.execute(query, (aluno_id,))
data = cur.fetchall()
if len(data) <= 0:
return Response(status=404)
else:
aluno = {
'nome': data[0][0],
'numero': data[0][1],
'password': data[0][2]
}
js = json.dumps(aluno)
resp = Response(js, status=200, mimetype='application/json')
resp.headers['Links'] = 'http://127.0.0.1/aluno'
return resp
#app.route('/v1.0/aluno/delete/<int:aluno_id>', methods=['POST'])
def aluno_delete(aluno_id):
if request.method == 'POST' and request.form['_method'] == 'delete':
query = "DELETE FROM aluno WHERE NUMERO = %s"
cur = mysql.connection.cursor()
cur.execute(query, (aluno_id,))
mysql.connection.commit()
cur.fetchall()
cur.close()
return Response(status=200)
#app.route('/v1.0/aluno/update/<int:aluno_id>', methods=['POST'])
def aluno_update(aluno_id):
form = AlunoForm(request.form)
if request.method == 'POST' and form.validate():
nome = request.form["nome"]
numero = request.form["numero"]
password = request.form["password"]
cur = mysql.connection.cursor()
query = "UPDATE aluno SET NOME=%s, NUMERO=%s, PASSWORD=%s WHERE NUMERO = %s"
cur.execute(query, (nome, numero, password, aluno_id))
mysql.connection.commit()
cur.execute(
"SELECT NOME, NUMERO FROM aluno WHERE NUMERO = %s", (aluno_id,))
data = cur.fetchall()
cur.close()
print(" * DATA ")
print(data)
aluno = {
'nome': data[0][0],
'numero': data[0][1]
}
js = json.dumps(aluno)
resp = Response(js, status=200, mimetype='application/json')
resp.headers['Links'] = 'http://127.0.0.1/aluno'
return resp
elif request.method == 'POST' and not form.validate():
resp = Response(status=400)
resp.headers['Links'] = 'http://127.0.0.1/aluno'
return resp
FRONT-END SIDE
{% endblock %}
<script type="text/javascript" src="{{url_for('static', filename='js/jquery-3.2.1.min.js') }}"></script>
<script type="text/javascript" src="{{url_for('static', filename = 'js/bootstrap.min.js')}}"></script>
<script>
function aluno_update(){
try{
let formElement = document.getElementById("aluno_update")
//let formData = formElement.
//console.log(formData)
$.ajax({
type: "POST",
url: "http://127.0.0.1:80/v1.0/aluno/update/{{aluno['numero']}}",
data: {'nome': 'João Luis','numero':'16172','password':'Password'},
//dataType: 'json',
success: function(data){
//location.href = "http://127.0.0.1:3000/v1.0/alunos/"
alert(data)
console.log(data)
},
error(jqXHR,JQueryXHR,errorThrown){
//console.log(formData)
alert(jqXHR)
alert(JQueryXHR)
alert(errorThrown)
console.log(jqXHR)
console.log(JQueryXHR)
console.log(errorThrown)
}
})
}catch(err){
alert(err)
}
}
</script>
I have tried using POSTMAN instead of the regular web browser. To make the request to the API. But i get the same response: 'This page was not found'
At least i was expecting some sort of 400 Bad Request or something like that.
https://github.com/joaogracio/SqlParser
Form validation fails and you get 400 according to the code below
elif request.method == 'POST' and not form.validate():
resp = Response(status=400)
resp.headers['Links'] = 'http://127.0.0.1/aluno'
return resp
I need to let the Django auto download the generated file.
Tried all different solutions online, none of them works.
Views.py
def validate(request):
if request.method == 'POST':
filename = request.POST.get('source_file')
file_path = os.path.join(settings.MEDIA_ROOT, 'SourceFiles', filename)
region = request.POST.get('region')
product_type = request.POST.get('product_type')
result = validateSource.delay(file_path, region, product_type)
output_filepath, log_filepath = result.get()
if os.path.exists(output_filepath) and os.path.exists(log_filepath):
zip_filename = zipFiles([output_filepath, log_filepath], filename)
zip_filepath = os.path.join(settings.MEDIA_ROOT, zip_filename)
response = FileResponse(open(zip_filepath, 'rb'), as_attachment=True)
return response
raise Http404
Template: code for the form POST.
$(document).on('submit', '#productForm', function(e){
e.preventDefault();
var inputFilePath = document.getElementById('sourceFileInput').files.item(0).name;
$.ajax({
method: 'POST',
url: 'validate/',
data: {
source_file: inputFilePath,
region: $("#Region-choice").val(),
product_type: $("#Product-type").val()}
})
.done(function(){
document.getElementById('lblStatus').innerHTML = "Result: <br/>"
document.getElementById('lblStatusContent').innerHTML = "Success!"
})
.fail(function(req, textStatus, errorThrown) {
document.getElementById('lblStatus').innerHTML = "Result: <br/>"
alert("Something went wrong!:" + textStatus + ' ' + errorThrown )
});
});
});
It's not possible to download files to your computer via an ajax (XHR) request. So you need to redirect the user actually (setting window.location) to a view that downloads the file. Or you can add as a result of the successful POST a button the current page so the user can download the file. In any case, you need to move the file download to a different view so a standard GET request can fetch it.
But your code to return the file in Django (using FileResponse) is correct.
There's also an explanation with an alternative way of doing it here
def validate(request):
if request.method == 'POST':
filename = request.POST.get('source_file')
file_path = os.path.join(settings.MEDIA_ROOT, 'SourceFiles', filename)
region = request.POST.get('region')
product_type = request.POST.get('product_type')
result = validateSource.delay(file_path, region, product_type)
output_filepath, log_filepath = result.get()
if os.path.exists(output_filepath) and os.path.exists(log_filepath):
zip_filename = zipFiles([output_filepath, log_filepath], filename)
zip_filepath = os.path.join(settings.MEDIA_ROOT, zip_filename)
with open(zip_filepath, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/force-download")
response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(zip_filepath)
return response
raise Http404
Clicking on the submit button literally does nothing. Submitting a blank form will trigger the validation for the required fields, but filling out the form as required results in the form not submitting/submit button doing nothing. The template has the CSRF_Token, Submit Button is in the form tag, and the form tag has an action attribute pointing in the right direction. Chrome doesn't bark any errors so I'm stuck on how to proceed.
views.py
#blueprint.route("register/", methods=['GET', 'POST'])
def register():
"""Renders register page."""
form = RegisterForm()
if request.method == 'POST':
if not form.validate_on_submit():
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=False, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
company, err = get_company(form.organization.data)
if err:
company, err = create_company(form.organization.data)
if err:
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=False, message=err, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
customer, err = get_or_create_customer(
form.first_name.data + " " + form.last_name.data, form.email.data,
company_id, form.position.data, phone_number
)
if err:
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=False, message=err, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
if err:
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=False, message=err, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
else:
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=True, message=success_msg, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
return render_template('main/register.html', page_title="Service Registration",
form=form, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
#blueprint.route("register/", methods=['POST'])
def upload_register():
"""Handles file upload POSTs."""
first_name = request.form.get("first_name")
last_name = request.form.get("last_name")
name = request.form.get("first_name") + " " + request.form.get("last_name")
email = request.form.get("email")
filename = request.form.get("filename")
file_type = request.form.get("file_type")
if filename == '':
response = make_response("No selected file")
return response, 400
if check_file_type(file_type):
filename = clean_filename(filename)
filename = secure_filename(filename)
filename = unique_filename(filename)
response = generate_presigned_post(filename, file_type)
# CREATE DB REFERENCE
url = "http://nevcodocs.s3.amazonaws.com/Uploads/{}".format(filename)
instance = CustomerFileUpload.query.filter_by(url=url).first()
if not instance:
instance = CustomerFileUpload(url=url, email=email, name=name)
db.session.add(instance)
db.session.commit()
else:
instance.update(created_at=datetime.utcnow())
return response, 200
else:
response = make_response("Invalid file type")
return response, 500
javascript/jquery
// Enables/disables form submission and colors button accordingly
var enableSubmit = function(enabled) {
if (enabled) {
$('#submit_ticket').removeAttr('disabled');
$('#submit_ticket').removeAttr('style');
} else {
$('#submit_ticket').attr('disabled', 'disabled');
$('#submit_ticket').attr('style', 'background-color: rgba(244, 121, 32, 0.5) !important; border-color: rgba(244, 121, 32, 0.25) !important;');
}
};
$('#ticket-form').submit(function(event) {
enableSubmit(false);
showSpinner(true);
var validated = true;
var didSelectFile = true;
didSelectFile = validateField('#upload') && validated;
validated = didSelectFile && validated;
if (didSelectFile && !validateContentType()) {
$('invalid-upload-alert').show();
validated = false;
} else {
$('#invalid-upload-alert').hide();
}
if (validated) {
$('#filename').val($('#upload').val());
$('#file_type').val($('#upload').prop('files')[0].type);
$.ajax({
type: 'POST',
url: '/register/',
data: $('#ticket-form').serialize()
}).done(function(data) {
var formData = new FormData();
for (var key in data.data.fields) {
formData.append(key, data.data.fields[key]);
}
formData.append('file', $('#upload').prop('files')[0]);
var req = new XMLHttpRequest();
req.onload = function() {
showSpinner(false);
$('#ticket-form-failed').removeClass("support-form-show");
$('#ticket-form-failed').addClass("support-form-hide");
$('#ticket-form').removeClass("support-form-show");
$('#ticket-form').addClass("support-form-hide");
$('#ticket-form-success').removeClass("support-form-hide");
$('#ticket-form-success').addClass("support-form-show");
};
req.onerror = function() {
showSpinner(false);
$('#ticket-form-failed').removeClass("support-form-hide");
$('#ticket-form-failed').addClass("support-form-show");
};
req.open('POST', data.url);
req.send(formData);
}).fail(function(err) {
showSpinner(false);
$('#ticket-form-failed').removeClass("support-form-hide");
$('#ticket-form-failed').addClass("support-form-show");
});
} else {
showSpinner(false);
enableSubmit(true);
}
{% endif %}
if (!validated) {
event.preventDefault();
showSpinner(false);
enableSubmit(true);
}
});
What you have written looks really complicated, why not try something easy like-
#app.route("/connect",methods=['GET','POST'])
def connect():
if request.method=='GET':
return render_template('connect.html')
if request.method=="POST":
return render_template('Thankyou.html',name=request.form['name])
in you views.py and in your connect.html form just write-
<form name="connect" method="post" action="{{ url_for('connect') }}">
<input class="t1" type="text" id="email" name="email" placeholder="Your Email ID">
<input class="t2" type="text" id="name" name="name" placeholder="name">
<button class="btn btn-primary but" type="submit">Send</button>
</form>
the final page, Thankyou.html can look like this-
<p>Thanks for contacting me, {{ name }} </p>
I have implemented Paypal integration in my Django app using Django-paypal
and along with that, I have setup signal receivers according to the documentation.
But the problem is: everytime when someone makes a payment it is flagged as duplicate even I'm passing a random invoice id along with paypal dictionary.
Here's what I have tried:
From views.py:
def generate_cid():
chars = "".join([random.choice(string.ascii_lowercase) for i in range(5)])
digits = "".join([random.choice(string.digits) for i in range(4)])
cid = digits + chars
return cid
def payment_process(request):
minutes = int(request.user.tagging.count()) * 5
testhours = minutes / 60
hours = ''
if request.user.tagging.count() > 11:
# hours = str(round(testhours, 3))
hours = 5
# invoice = generate_cid()
user_info = {
"name": str(request.user.first_name + ' ' + request.user.last_name),
"hours": str(hours),
"taggedArticles": str(request.user.tagging.count()),
"email": str(request.user.email),
"date": str(datetime.date.today()),
}
paypal_dict = {
"business": settings.PAYPAL_RECEIVER_EMAIL,
"item_name": "Certificate of Completion",
"custom": json.dumps(user_info),
"invoice": str(generate_cid()),
"amount": "95.00",
"currency_code": "USD",
"notify_url": settings.host + '/users/paypal',
"return_url": settings.host + "/users/done/",
"cancel_return": settings.host + "/users/cancel/",
}
# Create the instance.
form = PayPalPaymentsForm(initial=paypal_dict)
context = {"form": form}
return render(request, "users/generateCert.html", context)
From signals.py:
def show_me_the_money(sender, **kwargs):
ipn_obj = sender
# Undertake some action depending upon `ipn_obj`.
if ipn_obj.payment_status == ST_PP_COMPLETED:
print('Payment is completed')
user_infor = ast.literal_eval(ipn_obj.custom)
if ipn_obj.receiver_email == settings.PAYPAL_RECEIVER_EMAIL:
print('And Payment is valid')
# generate and send an email with pdf certificate file to the user's email
user_infor = ast.literal_eval(ipn_obj.custom)
user_info = {
"name": user_infor['name'],
"hours": user_infor['hours'],
"taggedArticles": user_infor['taggedArticles'],
"email": user_infor['email'],
"date": user_infor['date'],
}
html = render_to_string('users/certificate_template.html',
{'user': user_info})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'filename=certificate_{}'.format(user_info['name']) + '.pdf'
pdf = weasyprint.HTML(string=html, base_url='http://8d8093d5.ngrok.io/users/process/').write_pdf(
stylesheets=[weasyprint.CSS(string='body { font-family: serif}')])
to_emails = [str(user_infor['email'])]
subject = "Certificate from Nami Montana"
email = EmailMessage(subject, body=pdf, from_email=settings.EMAIL_HOST_USER, to=to_emails)
email.attach("certificate_{}".format(user_infor['name']) + '.pdf', pdf, "application/pdf")
email.content_subtype = "pdf" # Main content is now text/html
email.encoding = 'us-ascii'
email.send()
#receiver(invalid_ipn_received)
def do_not_show_me_the_money(sender, **kwargs):
print('And Payment is not valid')
ipn_obj = sender
user_infor = ast.literal_eval(ipn_obj.custom)
to_emails = [str(user_infor['email'])]
subject = "Certificate"
# message = 'Enjoy your certificate.'
email = EmailMessage(subject, body='Unfortunately, there\'s something wrong with your payment.Check your'
+ 'paypal account, please!',
from_email=settings.EMAIL_HOST_USER, to=to_emails)
# email.content_subtype = "pdf" # Main content is now text/html
# email.encoding = 'us-ascii'
email.send()
valid_ipn_received.connect(show_me_the_money)
Actually, I'm receiving both (Success & Fail) signals with a short difference of time(approx 2 min) for a single transaction.
And below is the screenshot for how IPNs received in Django admin:
Also, From the console:
In the signals.py both valid and invalid IPN received called, that's why it returns invalid IPN before sending the email.
Here is the correct and working signals.py:
def show_me_the_money(sender, **kwargs):
ipn_obj = sender
# Undertake some action depending upon `ipn_obj`.
if ipn_obj.payment_status == ST_PP_COMPLETED:
print('Payment is completed')
user_infor = ast.literal_eval(ipn_obj.custom)
if ipn_obj.receiver_email == settings.PAYPAL_RECEIVER_EMAIL:
print('And Payment is valid')
# generate and send an email with pdf certificate file to the user's email
user_infor = ast.literal_eval(ipn_obj.custom)
user_info = {
"name": user_infor['name'],
"hours": user_infor['hours'],
"taggedArticles": user_infor['taggedArticles'],
"email": user_infor['email'],
"date": user_infor['date'],
}
html = render_to_string('users/certificate_template.html',
{'user': user_info})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'filename=certificate_{}'.format(user_info['name']) + '.pdf'
pdf = weasyprint.HTML(string=html, base_url='http://8d8093d5.ngrok.io/users/process/').write_pdf(
stylesheets=[weasyprint.CSS(string='body { font-family: serif}')])
to_emails = [str(user_infor['email'])]
subject = "Certificate from Nami Montana"
email = EmailMessage(subject, body=pdf, from_email=settings.EMAIL_HOST_USER, to=to_emails)
email.attach("certificate_{}".format(user_infor['name']) + '.pdf', pdf, "application/pdf")
email.content_subtype = "pdf" # Main content is now text/html
email.encoding = 'us-ascii'
email.send()
else:
payment_was_flagged.connect(do_not_show_me_the_money)
def do_not_show_me_the_money(sender, **kwargs):
print('And Payment is not valid')
ipn_obj = sender
user_infor = ast.literal_eval(ipn_obj.custom)
to_emails = [str(user_infor['email'])]
subject = "Certificate from Nami Montana"
# message = 'Enjoy your certificate.'
email = EmailMessage(subject, body='Unfortunately, there\'s something wrong with your payment as it\'s'
'not validated.Check your PayPal account, please!',
from_email=settings.EMAIL_HOST_USER, to=to_emails)
email.send()
valid_ipn_received.connect(show_me_the_money)
Just need to call invalid_ipn only in case of an invalid payment.