I'm using Bootbox along with Ajax to delete a listing in my app which is calling a DeleteView but after I confirm the deletion, nothing changes.
View.py
class FileDelete(DeleteView):
model = Uploaded
success_url = reverse_lazy('index')
template_name = 'FileManagement/delete_file.html'
Script
<script>
$(".delete-file").click(function () {
var button = $(this);
var id = button.attr("data-id");
console.log(id);
bootbox.confirm("Are you sure you want to delete this file?",
function (result) {
if (result) {
$.ajax({
method: "GET",
url: "delete/" + id,
success: function(){
}
});
}
});
});
</script>
Urls.py
url(r'^delete/(?P<pk>\d+)/$', views.FileDelete.as_view(), name="delete_file")
I haven't finished the success part but it's still not deleting from the database.
You should use POST request instead of GET. Reference
Also, do not forget to include csrf_token.
<script>
$(".delete-file").click(function () {
var button = $(this);
var id = button.attr("data-id");
console.log(id);
bootbox.confirm("Are you sure you want to delete this file?", function (result) {
if (result) {
data = {
csrfmiddlewaretoken: "{{ csrf_token }}",
id: id
}
var posting = $.post("{% url 'delete_file' %}", data);
posting.done(function (data) {
// done
});
posting.fail(function (data) {
// fail
});
}
});
});
</script>
Related
currently when i submit the function first takes me to the api page where i have to click on post again for the results to update in the database then click on back button and refresh the page to see the updated data, it will be nice if the reduce button could update and display the data on the table without redirecting to the api page. Thank You, Please Help. trying to render the data here
#api_view(['POST'])
def sRd(request, pk):
sw = get_object_or_404(Swimmers,id=pk) # gets just one record
current_sessions = sw.sessions + 10
sw.sessions = current_sessions # updates just the one in memory field for sw (for the one record)
sw.save() # you may want to do this to commit the new value
serializer = SubSerializer(instance=sw, data=request.data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
return JsonResponse(data=serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
Want to render the data here on this page:
return render(request, 'accounts/modals/swimming/_vw_table.html', {'sw': sw})
The solution was to use Ajax asynchronous to be able to process data on the backend and display the results on the frontend using jQuery or any of the frontend framework. You must also include a csrf token or exempt it using #csrf_token by adding the plugin
from django.views.decorators.csrf import csrf_protect
<script type="text/javascript">
// CSRF TOKEN //
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
//Post Button Working With View Function sRd
$(document).ready(function () {
$("#post-form").submit(function (event) {
event.preventDefault();
$.ajax({
headers: {
'Content-type':'application/json',
'X-CSRFToken': csrftoken,
},
url: "{% url 'srd' srd.pk %}",
type: "POST",
data: $('#post-form').serialize(),
success: function (data) {
console.log(data);
}
}); // end ajax
});
});
</script>
Background:
Working in a Django application, I have a template that performs an action (makes a payement) using an external API. The API call is done in Javascript.
On Success, the API returns a response object. This works well on tests.
function makePayment(applicationAmount) {
let paymentEngine = RmPaymentEngine.init({
key: 'abcd'
firstName: '{{ user.f_name }}',
onSuccess: function(response) {
console.log('callback Successful Response', response);
// TODO: Add a function to post the payment records to the database
// response from the API contains a dictionary like (read json) object
// how can I get that response object in Python and use those response
// object values to update a django model database records
},
onError: function(response) {
console.log('callback Error Response', response);
// TODO: Add a function to throw an error message
},
onClose: function() {
console.log("closed");
}
});
}
Question:
How can I get that onSuccess response object variables in Python and use those response object values to update a django model database records?
Looked at this link: How do I return the response from an asynchronous call? but can't seem to implement my need.
I'd be happy to be directed to a simple resource that explains the procedure, not something very involved that takes hours to understand.
Using ideas from #Lag11 and #Arount and a wonderful tutorial here, I created 2 function based views, one to just serve the 'page' the other to handle the 'page post to DB'.
Summary, I did this in the template:
function makePayment(applicationAmount) {
let paymentEngine = RmPaymentEngine.init({
key: 'abcd'
firstName: '{{ user.f_name }}',
onSuccess: function(response) {
console.log('callback Successful Response', response);
// start new additions
data = {
"payer_email": "{{ user.email }}",
"payer_phone": "{{ user.phone }}",
"payment_amount_total": response.amount,
}
$.ajax({
type: 'POST',
url: "{% url 'post_purchase_form' %}",
data: data,
onSuccess: function (response) {
console.log('callback db post Successful', response);
},
error: function (response) {
// alert the error if any error occured
alert(response);
}
})
// end new additions
},
onError: function(response) {
console.log('callback Error Response', response);
// TODO: Add a function to throw an error message
},
onClose: function() {
console.log("closed");
}
});
}
And this in the views.py:
def application_form_view(request):
user = request.user
form = ApplicationForm(instance=user)
return render(request, 'application_form.html', {'form': form, 'user': user})
def post_application_form_view(request):
# request should be ajax and method should be POST.
if request.is_ajax and request.method == "POST":
# get the form data
form = ApplicationForm(request.POST, request.FILES)
# save the data and after fetch the object in instance
if form.is_valid():
instance = form.save()
# serialize in new FormPurchase object in json
ser_instance = serializers.serialize('json', [ instance, ])
# send to client side.
return JsonResponse({"instance": ser_instance}, status=200)
else:
# some form errors occured.
return JsonResponse({"error": form.errors}, status=400)
# some error occured
return JsonResponse({"error": "unknown errors"}, status=400)
This is what My ajax call looks like
$.ajax({
url:"{% url 'handsontable' %}",
data: {'getdata': JSON.stringify(hot.getData())},
dataType: 'json',
type: 'POST',
success: function (res, status) {
alert(res);
alert(status);
},
error: function (res) {
alert(res.status);
}
});
This is what my django view looks like.
if request.method == 'POST':
request_getdata = request.POST.get('getdata', 'None')
return HttpResponse(request_getdata)
The alerts in ajax return the data and "success". But my HttpResponse returns "None".
Any idea why it is not passing the data through? Thanks!
First off you are trying to POST to a html file
url:"/utility_tool/decisions/solution_options/handsontable.html",
Instead, it should be a url to a view.
Second, the ajax post request should have the csrftoken in it's header and you can set it up like this:
<script type="text/javascript">
// using jQuery get csrftoken from your HTML
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
// if not safe, set csrftoken
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$.ajax({
url: "{% url 'name of the view from urls.py' %}",
data: {
// here getdata should be a string so that
// in your views.py you can fetch the value using get('getdata')
'getdata': JSON.stringify(hot.getData())
},
dataType: 'json',
success: function (res, status) {
alert(res);
alert(status);
},
error: function (res) {
alert(res.status);
}
});
</script>
And in your django view:
# views.py
from django.http import JsonResponse
def someView(request):
if request.method == 'POST':
# no need to do this
# request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
request_getdata = request.POST.get('getdata', None)
# make sure that you serialise "request_getdata"
return JsonResponse(request_getdata)
And in your urls:
# urls.py
urlpatterns = [
# other urls
path('some/view/', views.someView, name='name of the view in urls.py'),
]
I cannot add comments because I do not yet have up to 50 reputations as demanded by StackOverflow. This is supposed to be a comment under the answer provided by #abybaddi009. He has done a very good job thus far but the answer needs a finishing touch.
In the view
request_getdata = request.POST.get('getdata', None) does not work
but this does
body = request.body.decode('utf-8')
data = body[3]
request.body.decode('utf-8') returns a string which would look something like getdata=your_data you can then use string manipulation techniques or regex to extract your data.
What you need to do is :
code for ajax call ( in js file) to send the data to the view
jQuery.ajax(
{
'url': "url_pattern_in_urls_py_file/",
'type': 'POST',
'contentType': 'application/json; charset=UTF-8',
'data': JSON.stringify({'updated_data':your_data_val}),
'dataType': 'json',
'success': function ( return_data ) {
//success body
}
}
);
code in django view with respect to above POST ajax call to receive the data
import json
if request.method == 'POST':
updatedData=json.loads(request.body.decode('UTF-8'))
I added return false; at the end of the ajax request and it worked. I printed out the values in the view instead of using HttpResponse.
When using {% url 'query' %} inside an AJAX get call is returning a string but when I put a static url it works properly.
I'm using Django-Filters and Django-rest-framework in installed apps.
url.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^query/$', 'my_app.views.app_function', name='query')
]
app.js
$(document).ready(function(){
// LOAD COOKIE
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function callServer () {
$.ajax({
type: 'GET',
url: "{% url 'query' %}",
success: function (json) {
console.log(json)
},
error: function(x, t, m) {
if(t==="timeout") {
alert("got timeout");
} else {
alert(t);
}
},
headers: {
'X-CSRFToken': csrftoken
}
});
}
$("#query").click(function () {
$('#sub').submit(function (e) {
e.preventDefault();
});
return callServer();
});
});
views.py
class AppFilter(django_filters.FilterSet):
class Meta:
model = Post
fields = ['first', 'second']
#api_view(['GET'])
def app_function(request):
qs = Post.objects.all()
f = AppFilter(request.GET, queryset=qs)
serializer = PostSerializer(f, many=True)
return Response(serializer.data)
forms.py
class QueryForm(forms.Form):
first = forms.TypedChoiceField(
widget=forms.Select,
choices=choice_dict1
)
second = forms.TypedChoiceField(
widget=forms.Select,
choices=choice_dict2
)
Any help before I burn the place?
Django would not be able to resolve {% url 'query' %} in JS file, since that's client side stuff. reverse url is resolved at the time of html file rendering.
What you can do is, pass that url as init() function of that JS module from html file:
<!-- In your Template file -->
<script>
$(function(){
app.init("{% url 'query' %}");
});
</script>
And export the app module from js file. Set that url as a variable, and use it in ajax call.
The problem is that your javascript file (app.js) is probably not the template. You don't show it, but I assume you have an HTML file that is loading the app.js file. The HTML file is where the template variables and such will get expanded. The simplest way to resolve this is to embed the javascript code into your HTML file inside a <script> tag.
There is a library for Flask called Flask-JSGlue that solves this problem and lets you use template variables in your javascript files, but I cannot find a similar library for Django.
I have this code in AngularJS:
myApp.controller('LoginCtrl', function($scope, $http){
$scope.formData = {};
$scope.doLogin = function(url, pass){
$http({
url: url,
method: "POST",
data: $.param($scope.formData)
}).success(function(data) {
console.log(data)
});
}
});
And in the beckend (Flask), I have this:
def user_authenticate():
login = request.args.get('login')
password = request.args.get('password')
print login, password
The problem is that request.args come empty.
UPDATE
After have a lot of problems with this, I solve using another Stackoverflow answer. So, I got this code:
ANGULARJS
$scope.doLogin = function(url, pass){
$http({
url: url,
method: "POST",
headers: { 'Content-Type': 'application/json' },
data: JSON.stringify(data)
}).success(function(data) {
console.log(data)
});
}
FLASK
def view_of_test():
post = request.get_json()
param = post.get('param_name')
OLD VERSION
I just figured that I need to change my code to this:
AngularJS:
myApp.controller('LoginCtrl', function($scope, $http){
$scope.formData = {};
$scope.doLogin = function(url, pass){
$http({
url: url,
method: "POST",
data: $.param($scope.formData),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function(data) {
console.log(data)
});
}
});
Just include the 'Content-Type' header.
Flask:
def user_authenticate():
login = request.form.get('login')
password = request.form.get('password')
print login, password
Instead of use request.args, use request.form.