AJax does not seem to work on the delete button - django

I am really new to ajax. I want to delete the entry from database on button click and I do not want the page to reload. but the ajax doesn't seem to work at all. What is wrong in my code? Please suggest the correct code. Thanks in advance.
<script>
$(document).on('click','#delete',function(){
var a ;
a=confirm("Do you really want to delete the user?");
if(a==true){
var newurl = "{% url 'NewApp:centredelete' pk=1%}"
var id = $(this).attr('name')
$.ajax(
{
type:"GET",
url: "newurl.replace('1',id);",
data:{
delete:True
},
success: function( data )
{
if(data.success == true){
$(id).remove();
}
else{
alert(data.error)
}
}
})}
});
</script>
views.py
def CentreDeleteView(request, pk):
centre = Centre.objects.get(pk=pk)
centre.delete()
return HttpResponseRedirect(reverse('NewApp:centrelist'))
edit:
urls.py
url(r'^centredelete/(?P<pk>\d+)/$',views.CentreDeleteView,name='centredelete'),
I am getting "Not Found: /NewApp/centrelist/url.replace('1',id);
" in the terminal. I don't know why it is taking the wrong url.

Kindly add your url file here and mention here the response on server terminal

replace "newurl.replace('1',id);" with newurl.replace('1',id) in your ajax.
You've used double quotes around newurl.replace('1',id) so the url will send as is instead of replacing '1' with the required id.

Related

Avoid double call GET Ajax load

Well, I'm trying to create a graphical interface for a database using django.
I have to say that I'm trying to learn so I don't have too much experience with Frameworks, just with pure code.
The doubt I have is:
-When trying to create a filter system with checkboxes I have used Ajax to be able to update the view without having to refresh. Like this:
$(document).on('click','#console_check_filter',function(){
var ps_id;
ps_id = $(this).attr("data-posts-id");
$.ajax({
url: "{% url 'list-view' %}",
method: 'POST',
data: {
'getfilter': ps_id,
'csrfmiddlewaretoken': '{{ csrf_token }}',
},
success: function (res, status,data) {
$("#list").load("/game/list-view");
},
error: function (res,ras,rus) {
}
});
});
But I had the error that for every call I made with POST the AJAX function ().load() made another call which eliminated the variable that gave me the POST. This made it impossible for me to use the information received from the POST to create the filter.
Result: I click on the checkbox and in the console I get a call with the filtered list and then another one without filter, and as it is not only the last one that is rendered, which has no data.
To solve this I have used a globar variable to save the value in the POST and the ().load() return to make the GET call using the value saved in the GLOBAL.
filet=""
def game_list(request):
global filet
context = {}
game_filter = request.GET.get('console_check_filter')
games = Game.objects.all()
game_post = games
data = {'success': False}
page = request.GET.get('page',1)
game_console_filter=""
context['games'] = games
#if request.method=='POST':
game_console_filter = request.POST.get('getfilter')
if not game_console_filter:
game_console_filter = request.GET.get('getfilter')
if request.method=="POST":
filet = get_game_console_filter(request,game_console_filter)
context['games'] = games
context['game_post'] = filet
return render(request,'Jocs/list-view.html',context )
This doesn't seem elegant to me, I'm out of the woods, yes, but I don't think it's the best solution.
Any idea to avoid this happening to me?
A greeting and thank you very much for everything
Apparently I am more stupid than I thought. In the end the solution was to send the variable by URL. Example:
AJAX:
$(document).on('click','#console_check_filter',function(){
var ps_id;
ps_id = $(this).attr("data-posts-id");
$.ajax({
url: "{% url 'list-view' %}",
method: 'POST',
data: {
getfilter': ps_id,
csrfmiddlewaretoken': '{{ csrf_token }}',
},
success: function (res, status,data) {
$("#list").load("/game/list-view/?filters="+ps_id); > <-----HERE
},
error: function (res,ras,rus) {
}
});
});
views.py:
#if request.method=='POST':
game_console_filter = request.POST.get('getfilter')
if not game_console_filter:
game_console_filter = request.GET.get('filters') <---HERE
I think that if this is the right way to proceed, at least it's more elegant.
I hope someone else will find this answer useful.
Sorry for the inconvenience and for asking trivial questions. Greetings to all.

Update / Delete a tab from a facebook page using the Graph API returns "(#210) Subject must be a page."

I am trying to delete an application tab from a facebook page.
According to the documentation, I should issue a DELETE request to "https://graph.facebook.com/PAGE_ID/tabs/TAB_ID" with a PAGE access token, but when I do so I get the error "(#210) Subject must be a page."
The same happens when trying to update a tab.
I have requested the user for "manage_pages" permission and I have the correct access_token (Adding a tab works perfectly).
the exact request is: https://graph.facebook.com/212757048770606/tabs/app_289329597785433 (with an access token)
Does anyone know what am I doing wrong?? or is there an open bug report?
Thanks alot
I don't have a solution for you, but I do know that I had some problems with removing a tab that boiled down to the fact that the tab's ID (returned from a call to get /PAGE_ID/tabs) already includes the page ID and "tabs" path.
Initially I was building my URL by taking the tab ID and sticking it on the end of /PAGE_ID/tabs/, but that didn't work because the URL ended up being something like /12345/tabs/12345/tabs/app_4567. Once I realized that the tab ID was sort of "compound" already, I got the Remove to work.
Add the page access token to the call of Facebook API
var PageAccessToken = 123456789123456789123456789123456789;
FB.api(
"/{page_id}/tabs",
"POST",
{
"object": {
"app_id": "{page_id}"
}
},{
"access_token": PageAccessToken
},
function (response) {
if (response && !response.error) {
console.log(response);
} else {
console.log(response.error);
}
}
);
function DeleteTabPage(){
var pid = page_id;
var at = access_tocken;
debugger;
FB.api(pid + '/tabs/app_{your app id}', 'DELETE', { app_id: your app id, access_token: at }, function (response) {
debugger;
if (!response || response.error) {
debugger;`enter code here`
alert('Facebook add app error ' + response.error);
} else {
console.log(response);
debugger;
// alert('App has been added');
}
}); /* end of page/tabs*/
}

jQuery .load() not working in Django

I'm trying to make a call to a url in Django and load the contents of it. Right now I have:
<script>
$('.myClass').load('{% url update_dropdown %}',
{'kind': "Book" },
function(data){
alert(data);
});
</script>
And then the view that update_dropdown refers to is:
#csrf_exempt
def update_dropdown(request):
category = request.POST.get('kind', None)
all =False;
args = {
"label":category,
"all":all
}
return render_to_response('template.html',(args))
However, the .load() won't work for some reason. If I go directly to the URL it shows the data I expect, but .load() won't cooperate. I know it's not a display issue, as the alert will not work (unless I remove the #csrf_exempt, then it alerts the HTML of the error page)
I'm pretty confused as to what's going on, and I've been debugging this and trying to find the error for hours now, any help would be appreciated .
I can get it to work if I make the return type a JSON object and use getJSON(), but I'd prefer not to
Try wrapping it in a ready:
$(document).ready( function () {
$('.myClass').load('{% url update_dropdown %}',
{'kind': "Book" },
function(data){
alert(data);
});
});
Apparently it was an issue with the jQuery uiSelect library I was using. It was out of date and causing errors.

"CSRF token missing or incorrect" while post parameter via AJAX in Django

I try to post parameter like
jQuery.ajax(
{
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': "{content:'xxx'}",
'dataType': 'json',
'success': rateReviewResult
}
);
However, Django return Forbidden 403. CSRF verification failed. Request aborted.
I am using 'django.middleware.csrf.CsrfViewMiddleware' and couldn't find how I can prevent this problem without compromising security.
You can make AJAX post request in two different ways:
To tell your view not to check the csrf token. This can be done by using decorator #csrf_exempt, like this:
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def your_view_name(request):
...
To embed a csrf token in each AJAX request, for jQuery it may be:
$(function () {
$.ajaxSetup({
headers: { "X-CSRFToken": getCookie("csrftoken") }
});
});
Where the getCookie function retrieves csrf token from cookies. I use the following implementation:
function getCookie(c_name)
{
if (document.cookie.length > 0)
{
c_start = document.cookie.indexOf(c_name + "=");
if (c_start != -1)
{
c_start = c_start + c_name.length + 1;
c_end = document.cookie.indexOf(";", c_start);
if (c_end == -1) c_end = document.cookie.length;
return unescape(document.cookie.substring(c_start,c_end));
}
}
return "";
}
Also, jQuery has a plugin for accessing cookies, something like that:
// set cookie
$.cookie('cookiename', 'cookievalue');
// read cookie
var myCookie = $.cookie('cookiename');
// delete cookie
$.cookie('cookiename', null);
The simplest way I have found is to include the {{csrf_token}} value in the data:
jQuery.ajax(
{
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': {
'content': 'xxx',
'csrfmiddlewaretoken': '{{ csrf_token }}',
},
'dataType': 'json',
'success': rateReviewResult
}
);
It took me a while to understand what to do with the code that Daniel posted. But actually all you have to do is paste it at the beginning of the javascript file.
For me, the best solution so far is:
Create a csrf.js file
Paste the code in the csrf.js file
Reference the code in the template you need it
<script type="text/javascript" src="{{ STATIC_PREFIX }}js/csrf.js"></script>
Notice that STATIC_PREFIX/js/csrf.js points to my file. I am actually loading the STATIC_PREFIX variable with {% get_static_prefix as STATIC_PREFIX %}.
Advanced tip: if you are using templates and have something like base.html where you extend from, then you can just reference the script from there and you don't have to worry anymore in there rest of your files. As far as I understand, this shouldn't represent any security issue either.
Simple and short
$.ajaxSetup({
headers: { "X-CSRFToken": '{{csrf_token}}' }
});
OR
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", '{{csrf_token}}');
}
}
});
docs
For lack of a straight forward answer, you just have to add the header X-CSRFToken to the ajax request which is in the cookie csrftoken. JQuery doesn't do cookies (for some reason) without a plugin so:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
and the minimal code change is:
$.ajax({
headers: { "X-CSRFToken": $.cookie("csrftoken") },
...
});
The fastest solution without any plugins if you are not embedding js into your template is:
Put <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script> before your reference to script.js file in your template, then add csrfmiddlewaretoken into your data dictionary:
$.ajax({
type: 'POST',
url: somepathname + "do_it/",
data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
success: function() {
console.log("Success!");
}
})
If you do embed your js into the template, it's as simple as: data: {csrfmiddlewaretoken: '{{ csrf_token }}'}
I got the same issue yesterday and thought it would help people if there were a simple way to handle it, so I wrote a jQuery plugin for that: jquery.djangocsrf. Instead of adding the CSRF token in every request, it hooks itself on the AjaxSend jQuery event and adds the client cookie in a header.
Here’s how to use it:
1- include it:
<script src="path/to/jquery.js"></script>
<script src="path/to/jquery.cookie.js"></script>
<script src="path/to/jquery.djangocsrf.js"></script>
2- enable it in your code:
$.djangocsrf( "enable" );
Django always add the token in a cookie if your template uses {% csrf_token %}. To ensure it always adds it even if you don’t use the special tag in your template, use the #ensure_csrf_cookie decorator:
from django.views.decorators.csrf import ensure_csrf_cookie
#ensure_csrf_cookie
def my_view(request):
return render(request, 'mytemplate.html')
Note: I’m using Django 1.6.2.
Thank you everyone for all the answers. I am using Django 1.5.1. I'm a little late to the party, but here goes.
I found the link to the Django project to be very useful, but I didn't really want to have to include the extra JavaScript code every time I wanted to make an Ajax call.
I like jerrykan's response as it is very succinct and only adds one line to an otherwise normal Ajax call. In response to the comments below his comment regarding situations when Django template tags are unavailable, how about loading up the csrfmiddlewaretoken from the DOM?
var token = $('input[name="csrfmiddlewaretoken"]').prop('value');
jQuery.ajax({
type: 'POST',
url: url,
data: { 'csrfmiddlewaretoken': token },
dataType: 'json',
success: function(data) { console.log('Yippee! ' + data); }
});
EDIT March 2016
My approach to this issue over the past few years has changed. I add the code below (from the Django docs) to a main.js file and load it on every page. Once done, you shouldn't need to worry about the CSRF token with ajax again.
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');
Include x-csrftoken header in request:
var token = $('input[name="csrfmiddlewaretoken"]').prop('value');
jQuery.ajax({
type: 'POST',
url: url,
beforeSend : function(jqXHR, settings) {
jqXHR.setRequestHeader("x-csrftoken", get_the_csrf_token_from_cookie());
},
data: data,
dataType: 'json',
});
If, after reading other answers, someone is still struggling please try this:
$.ajax({
type: "POST",
beforeSend: function (request)
{
request.setRequestHeader("X-CSRF-TOKEN", "${_csrf.token}");
},
url: servlet_path,
data : data,
success : function(result) {
console.log("Success!");
}
});
Please not that when doing it this way make sure you don't have the {% csrf_token %} inside the <form></form> tags. Then as explained here add the following code to your javascript
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');
// using js fetch
// https://docs.djangoproject.com/en/3.1/ref/csrf/#setting-the-token-on-the-ajax-request
const request = new Request(
/* URL */,
{headers: {'X-CSRFToken': csrftoken}}
);
fetch(request, {
method: 'POST',
mode: 'same-origin' // Do not send CSRF token to another domain.
}).then(function(response) {
// ...
});
Just want to put it out here that if GET works in your use case, then it wouldn't need the CSRF token. For my use case, using GET was OK.
html
<form action="">
{% csrf_token %}
</form>
JS
<script>
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
const request = new Request(
'url_here',
{headers: {'X-CSRFToken': csrftoken}}
);
fetch(request, {
method: 'POST',
// mode: 'same-origin' optinal // Do not send CSRF token to another domain.
}).then(function(response) {
console.log(response);
});
</script>
reference link for more detail
As a summary for my mistakes:
Don't forget to set the request content type.
Get the csrf value, either from
The template {{ csrf_token }}
The cookie, use the snippet in django site
NB. The default cookie name is csrftoken, but can be overriden by CSRF_COOKIE_NAME setting.
The DOM, if you can't access the cookie (you set CSRF_USE_SESSIONS or CSRF_COOKIE_HTTPONLY to True)
document.querySelector('[name=csrfmiddlewaretoken]').value;
Set the request header, I'am using XMLHttpRequest
const Http = new XMLHttpRequest();
Http.setRequestHeader("X-CSRFToken", CSRF_VALUE);
Http.setRequestHeader("X_CSRFTOKEN", CSRF_VALUE);
The header name is managed by CSRF_HEADER_NAME setting, which its default is HTTP_X_CSRFTOKEN.
But: "The header name received from the server is normalized by converting all characters to uppercase, replacing any hyphens with underscores, and adding an 'HTTP_' prefix to the name" src.
So, If you set the HTTP_X_CSRFTOKEN header, Django will convert it to HTTP_HTTP_X_CSRFTOKEN which wis incorrect name and will raise CSRF missed error.
Http.setRequestHeader("X-CSRFToken", csrftoken); // This worked
Http.setRequestHeader("X-CSRFTOKEN", csrftoken); // Also this
Http.setRequestHeader("HTTP-X-CSRFToken", csrftoken); // Not working
Http.setRequestHeader("HTTP_X_CSRFTOKEN", csrftoken); // Not Working
Http.setRequestHeader("X_CSRFTOKEN", csrftoken); // Not working !!
Don't use url in ajax that is different than that of the browser 127.0.0.1 & localhost are not the same !!
No need to set data.append("csrfmiddlewaretoken", csrftoken); in the request body, As I know.

django-facebookconnect extended permissions

I am wanting to add some extended permissions to django-facebookconnect namely "email". After looking through the code I see that the actual connect is managed in javascript. So, I thought that something like this might work
{% load facebook_tags %}
<script type="text/javascript">
FB_RequireFeatures(["XFBML"], function() {
FB.Facebook.init("{{ facebook_api_key }}", "{% url facebook_xd_receiver %}"{%extended_permissions%});
});
function facebookConnect(loginForm) {
FB.Connect.requireSession();
FB.Facebook.get_sessionState().waitUntilReady(function(){loginForm.submit();});
}
function pushToFacebookFeed(data){
if(data['success']){
var template_data = data['template_data'];
var template_bundle_id = data['template_bundle_id'];
feedTheFacebook(template_data,template_bundle_id,function(){});
} else {
alert(data['errors']);
}
}
function pushToFacebookFeedAndRedirect(data){
if(data['success']){
var template_data = data['template_data'];
var template_bundle_id = data['template_bundle_id'];
feedTheFacebook(template_data,template_bundle_id,function(){window.location.href=template_data['url'];});
} else {
alert(data['errors']);
}
}
function pushToFacebookFeedAndReload(data){
if(data['success']){
var template_data = data['template_data'];
var template_bundle_id = data['template_bundle_id'];
feedTheFacebook(template_data,template_bundle_id,function(){window.location.reload();});
} else {
alert(data['errors']);
}
}
function feedTheFacebook(template_data,template_bundle_id,callback) {
FB.Connect.showFeedDialog(
template_bundle_id,
template_data,
null, null, null,
FB.RequireConnect.promptConnect,
callback
);
}
</script>
here is the extended_permissions tag
#register.simple_tag
def extended_permissions():
if hasattr(settings,'FACEBOOK_EXTENDED_PERMISSIONS'):
return """, {permsToRequestOnConnect: "%s"}""" % ','.join(settings.FACEBOOK_EXTENDED_PERMISSIONS)
return ''
In theory I think the above code should work. Actually it does work it just breaks the popup window functionality. When the user accepts the request from the app they are redirected(within the popup) to the home page. Before the edits the popup would close and the main browser window would be redirected to /facebook/setup.
Any suggestions would be greatly appreciated
I think the problem might be here:
FB.Facebook.init("{{ facebook_api_key }}", "{% url facebook_xd_receiver %}"{%extended_permissions%});
I bet it should be
FB.Facebook.init("{{ facebook_api_key }}", "{% url facebook_xd_receiver %}{%extended_permissions%}");
or possibly even
FB.Facebook.init("{{ facebook_api_key }}", "{% url facebook_xd_receiver %}?perms={%extended_permissions%}");
Not sure, but I never liked the js api anyways. If you're still running into problems, try my Django oauth implementation: https://github.com/dickeytk/django_facebook_oauth