Python 2.7 - Access Javascript file object in Django - javascript

I am building an app that sends multiple files as email attachments, using jQuery and Django 1.9.
I store the files in a buffer that the user can add and delete from, and sending them over a POST Ajax request as such:
//Build the message
message_buffer.forEach(function(entry){
body += '\n' + entry;
});
var files = $.merge(attachment_buffer.photos, attachment_buffer.documents);
var form = new FormData();
form.append("csrfmiddlewaretoken", csrf_token);
form.append("client_id", client_id);
form.append("subject", subject);
form.append("body", body);
form.append("files", files);
$.ajax({
url: window.location.origin + '/dashboard/ajax/send_message',
method: "post",
data: form,
processData: false,
contentType: false,
cache: false,
beforeSend: function(){
//Block UI
},
success: function(data){
if(data.status == 'success'){
console.log(data);
//Show success and clear all the data stores.
} else {
console.log(data.message);
}
},
error: function(err){
console.log(err.responseText);
}
});
Problem is when i get this buffer (a list of JS file objects) in my django view, they are gotten as unicode and i dont know how to parse them.
I need to be able to attach the files to the django EmailMessage instance like this:
for attachment in attachments:
mail.attach(attachment.name, attachment.read(), attachment.content_type)
The Django view code is:
if request.method == "POST":
client_id = request.POST['client_id']
subject = request.POST['subject']
body = request.POST['body']
attachments = []
if 'files' in request.POST.keys() and request.POST['files'] != '':
attachments = request.POST['files']
client = Client.get_client_by_id(request.user, client_id)
if client:
email_helper = EmailHelper()
email_sent = email_helper.send_email_with_attachments(request, client, subject, body, attachments)
And the email method:
def send_email_with_attachments(self, request, client, subject, message, attachments, from_email=settings.EMAIL_HOST_USER):
"""
Sends a simple text mail with attachments
:param request:
:param client:
:param subject:
:param message:
:param from_email:
:param attachments:
:return:
"""
# print type(encoding.smart_bytes(attachments))
# # for attachment in attachments:
# # print json.loads(attachment)
# #
# return False
try:
mail = EmailMessage(
self.clean_email_params(subject),
self.clean_email_params(message),
self.clean_email_params(from_email),
self.clean_email_params([client.email]),
reply_to=[from_email]
)
for attachment in attachments:
mail.attach(attachment.name, attachment.read(), attachment.content_type)
mail.send()
try:
# Log the sent email
email_log = SentEmailsLog()
email_log.user = request.user
email_log.client = client
email_log.subject = self.clean_email_params(subject)
email_log.content = self.clean_email_params(message)
email_log.to_email = str(self.clean_email_params([client.email]))
email_log.from_email = self.clean_email_params(from_email)
email_log.host_email = settings.EMAIL_HOST_USER
email_log.attachments = 'No'
email_log.save()
except Exception, e:
ErrorLogHelper.log_error(error_message=e, calling_function="EmailHelper.send_email_with_attachments")
return True
except Exception, e:
ErrorLogHelper.log_error(error_message=e, calling_function="EmailHelper.send_email_with_attachments")
return False
Please advice, thank you.

Try to explicitly encode your request body in view.py, like so:
body = request.POST['body'].encode('utf8')

Related

Why Ajax is triggering 500 internal error in django?

Does anyone know why I am getting 500 internal error when I try to call an Ajax function? I tried to send the response from view.py to Ajax function in 2 ways: JsonResponse (see else from view.py) and also with HttpResponse (see if from View.py).
My Hmtl form does have a csrf_token, so I added the header in ajax function, but still got 500 internal erorr. The data is saved into database but the response is not sent to ajax function.
View.py
## Ajax
#login_required
def SubmitModal(request):
if request.method == 'POST':
text = request.POST['Text']
date = request.POST['DatePicker']
time = request.POST['TimePicker']
T = SText()
T.User = request.user
T.Text = text
T.STime = date + ' ' + time
T.save()
return HttpResponse(json.dumps({'success': True}), content_type="application/json")
else:
return JsonResponse({'success': False})
file that contains ajax
$(document).ready(function () {
// Show the modal window when a button is clicked
$('#open-modal').click(function () {
$('#modal').modal('show');
});
// Close the modal window when a button is clicked
$('.close-modal').click(function () {
$('#modal').modal('hide');
});
// Handle the form submission
$('#modal-form').submit(function (event) {
event.preventDefault(); // Prevent the form from being submitted
var formData = $(this).serialize(); // Get the form data
// Submit the form data to the server using an AJAX request
$.ajax({
type: 'POST',
url: '/submit/',
headers: {'X-CSRFToken': '{{ csrf_token }}'},
data: formData,
dataType: "json",
success: function (response) {
if (response.success) {
$('#success-message').show();
} else {
$('#error-message').show();
}
},
error: function (xhr, status, error) {
console.log(error);
}
});
$(".textarea-input")[0].value = '';
$(".date-input")[0].value = '';
$(".time-input")[0].value = '';
});
});
If you're reproducing this in a non-production environment, you can set DEBUG=True in the settings file. Then when you make the call from your browser, the response will include details about what the issue is. You can also set the ADMINS variable to send exception tracebacks to the specified emails when they're encountered. More details here.
You can view the data being sent and received in the developer tools of the browser you are using.

How do I get the JSON values from the response in Groovy

I'm using the below function in Jenkins Shared Library.
/* The below function will list the groups */
def list_groups(server_url,each_group_name,authentication){
def groups_url = server_url + "/api/v1/groups"
def response = httpRequest consoleLogResponseBody: true,
contentType: 'APPLICATION_JSON',
customHeaders: [[maskValue: false, name: 'Authorization', value: authentication]],
httpMode: 'GET', ignoreSslErrors: true, responseHandle: 'NONE', url: groups_url,
validResponseCodes: '100:599'
if(response.status == 404){
throw new Exception("Server url not found! Please provide correct server URL.")
}
else{
if(response.status == 400 || response.status == 403){
throw new Exception("Invalid Access token or Access token expired!")
}
}
def result = readJSON text: """${response.content}"""
}
=====================================================================
I'm getting the below response,
Response Code: HTTP/1.1 200 OK
Response:
[{"id":2,"name":"Default User"},{"id":3,"name":"fos"},{"id":4,"name": "kXR"},{"id":5,"name": "Sgh"},{"id":6,"name":"ksn"},{"id":7,"name":"ALb"}]
Success: Status code 200 is in the accepted range: 100:599
Requirement:
I need to get the last output from the JSON body (id & name) ---> {"id":7,"name":"ALb"} from the response and to be printed and stored in a variable using groovy.
First, you need to Parse the response String to a JSON object, for this you can either use Jenkins native method readJSON, or something like JsonSlurperClassic. Then you can use JSON path expressions to extract the values. Check the following example.
def jsonObj = readJSON text: response.getContent()
def id = jsonObj.id[-1]
def name = jsonObj.name[-1]
echo "ID: $id | NAME: $name"

Not able to retrieve data values from Ajax GET call into Django view

I am trying to query the employee list based on parameter I send
through ajax call inside data, but it giving me an error (i want it
through GET req only )
Js ajax func
$(document).ready(function () {
$(".call_ajax").click(function () {
$.ajax({
url: "/employee_list",
type: "GET",
contentType: "application/json",
dataType: "json",
data: {
designation: "soft eng",
},
headers: {
"X-CSRFToken": csrftoken,
Authorization: my_token,
},
success: function (data) {
console.log(data);
},
error: function (xhr) {
//Do Something to handle error
console.log(xhr.error);
},
});
});
my view
#csrf_exempt
#api_view(['GET', 'POST', 'PUT', 'DELETE'])
#permission_classes([IsAuthenticated])
#authentication_classes([TokenAuthentication])
def employee_list(request):
if request.method == 'GET':
data_ = request.data['designation']
print(data_)
employees = Employee.objects.all()
students = Student.objects.all()
user = MyUser.objects.all()
serializer = EmployeeSerializer(employees, many=True)
serialized_sudents = StudentSerializer(students, many=True)
multi = {
'employees': serializer.data,
'students': serialized_sudents.data
}
# serializer2 = UserSerializer(user, many=True)
return JsonResponse(multi, safe=False)
error i am getting in browser
GET http://127.0.0.1:8000/employee_list/ 500 (Internal Server Error)
error in Django log
File "C:\Users\atif\PycharmProjects\CodePlatform\syntax_fight\api_\views.py", line 42, in employee_list
data_ = request.data['designation']
KeyError: 'designation'
request.data returns the parsed content of the request body.
This is similar to the standard request.POST and request.FILES
You can use request.GET.get('designation')
#csrf_exempt
#api_view(['GET', 'POST', 'PUT', 'DELETE'])
#permission_classes([IsAuthenticated])
#authentication_classes([TokenAuthentication])
def employee_list(request):
if request.method == 'GET':
data_ = request.GET.get('designation') # Here I made changes
print(data_)
employees = Employee.objects.filter(designation=data_) # Map parsed data with database field
students = Student.objects.all()
user = MyUser.objects.all()
serializer = EmployeeSerializer(employees, many=True)
serialized_sudents = StudentSerializer(students, many=True)
multi = {
'employees': serializer.data,
'students': serialized_sudents.data
}
# serializer2 = UserSerializer(user, many=True)
return JsonResponse(multi, safe=False)
or
You can override get_queryset method. As for query string parameters request.data holds POST data, you can get query string params through request.query_params
def get_queryset(self):
data = self.request.query_params.get('designation')
queryset = Model.objects.filter() # use whatever you want filter
return queryset
To know more about request.data and request.query_params, here is the link
Request parsing link
It is most probably because you are using GET, but the data resides in body. Have a look at this. To try to fix this, change your request method to POST:
$.ajax({
url: "/employee_list",
type: "POST",
...

Are there any other reason which can cause 403 error except absence of csrf token in ajax request + django?

The main reason of django + ajax 403 error is absence of csrf token, but in my case it's present and almost the same ajax function works fine. I'll also attach backend view function handling the response using djangorestframework.
$.ajax({
url: '/authsteptwo/',
type:'POST',
dataType: 'json',
data: { phone_number : phone_number, email : email, csrfmiddlewaretoken: "{{ csrf_token }}" },
success: function () {
// alert('succes');
setTimeout(
function()
{
alert('fine');
}, 0);
},
error : function() {
alert('fck');
}
})
view
#api_view(['POST', ])
def auth_step_two(request):
if request.method == 'POST':
phone_number = request.data['phone_number']
email = request.data['email']
# user = request.user.UserProfile
# user.email = email
# user.phone_number = phone_number
# user.save()
else:
print("WTF")
return Response(request.data)
console:
Failed to load resource: the server responded with a status of 403 (FORBIDDEN)
Are there any other reason which can cause 403 error ?
EDIT: I tried just to call ajax function out of all condition in the beggingign of the page, just after and it worked. But calling the same function onclick(without real data, so it's not related) fails wth 403 or also falls on jQuery click event. Very weird. Any suggestions what could it be?
EDIT: Oh, I figured out that no ajax function in fact working after first ajax auth call executed. I attach the code of first call which works and after that nothing works. Help me understand why?
$.ajax({
url: '/authfb/',
type:'POST',
dataType: 'json',
data: {"fb_first_name": fb_first_name, "fb_last_name": fb_last_name, "fb_username": fb_username, "fb_email":fb_email, "fb_id":fb_id, "fb_link":fb_link, csrfmiddlewaretoken: "{{ csrf_token }}" },
success: function () {
// alert('succes');
setTimeout(
function()
{
$('#hide_group').hide();
$('#show_group').show();
$('.loading_white_wall').fadeOut();
$('.greeting_title_name').html(fb_first_name);
if(fb_email){
$(".email_input").prop("value", fb_email);
}
else{
$(".email_input").prop("placeholder", 'E-mail');
}
}, 1000);
},
error : function(data) {
$('#hide_group').hide();
$('#error_group').show();
$('.loading_white_wall').fadeOut();
}
})
And also the exact code of handler, there is much but possible something somehow related, but most likely no much use of it:
#api_view(['POST', ])
def authfb(request):
require_more_data = True
if request.method == 'POST':
first_name = request.data['fb_first_name']
last_name = request.data['fb_last_name']
fb_username = request.data['fb_username']
fb_id = int(request.data['fb_id'])
fb_link = request.data['fb_link']
username = fb_username.replace(' ', '')
print(fb_link)
print (type(fb_id))
# print(username)
password = '11442358'
user = auth.authenticate(username=username, password=password)
# print(type(username))
# print(type(password))
if user is not None:
auth.login(request, user)
username = auth.get_user(request).username
print ('logged in succesfully')
# user1 = UserProfile.user.objects.get(username=username)
# if (user1.userprofile.phone_number):
# print ("hello")
# email = auth.get_user(request).UserProfile.email
# if phone_number and email:
# require_more_data = False
else:
user = User.objects.create_user(username=username, password=password)
userprofile = UserProfile.objects.create(user=user, first_name=first_name, last_name=last_name)
user = auth.authenticate(username=username, password=password)
auth.login(request, user)
print (userprofile)
else:
print("WTF")
return Response(request.data)
I found a solution in one of my old projects. If someone explains why this works and previous is wrong, I'll mark as correct.
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
var csrftoken = getCookie('csrftoken');
$.ajaxSetup({
headers: { "X-CSRFToken": getCookie("csrftoken") }
});
in ajax call
data: {"fb_first_name": fb_first_name,'csrfmiddlewaretoken': getCookie('csrftoken') },

Pass just one field via AJAX with Flask

I have a VERY simple HTML form with just one <input type='text'> field, an email address, that I need to pass back to a Python script via AJAX. I can't seem to receive the value on the other end. (And can all the JSON encoding/decoding be avoided, since there's just one field?)
Here's the code:
from flask import Flask, render_template, request, json
import logging
app = Flask(__name__)
#app.route('/')
def hello():
return render_template('index.htm')
#app.route('/start', methods=['POST'])
def start():
# next line outputs "email=myemail#gmail.com"
app.logger.debug(request.json);
email = request.json['email'];
# next line ALSO outputs "email=myemail#gmail.com"
app.logger.debug(email);
return json.dumps({ 'status': 'OK', 'email': email })
if __name__ == "__main__":
app.run()
And the Javascript that sends the AJAX from the HTML side--
$( "form" ).on( "submit", function( event ) {
event.preventDefault();
d = "email=" + $('#email').val(); // this works correctly
// next line outputs 'sending data: myemail#gmail.com'
console.log("sending data: "+d);
$.ajax({
type: "POST",
url: "{{ url_for('start') }}",
data: JSON.stringify(d),
dataType: 'JSON',
contentType: 'application/json;charset=UTF-8',
success: function(result) {
console.log("SUCCESS: ");
// next line outputs 'Object {email: "email=myemail#gmail.com", status: "OK"}'
console.log(result);
}
});
});
JSON.stringify is used to turn an object into a JSON-formatted string, but you don't have an object, just a string. Try this:
var d = { email: $('#email').val() };
JSON.stringify(d) will now turn that into a JSON-formatted string:
{email: "myemail#gmail.com"} which can be parsed by flask.
To do this without JSON:
var d = { email: $('#email').val() };
...
// AJAX
data: d,
success: ...
This will turn {email: "myemail#gmail.com"} into email=mymail#gmail.com and send that as body of the POST request. In Flask, use request.form['email'].

Categories

Resources