Python Django Ajax get request not working in def function - python

I'm trying to pass a variable from my JQuery Ajax object via get method to my views.py file (in django)
I was using a class before and it was working just fine..
views.py working code:
class AjaxHandlerView(View):
def get(self, request):
text = request.GET.get('button_text')
print()
print(text)
print()
if request.is_ajax():
return JsonResponse({'test': 'blah'})
return render(request,'home.html' , {'name': 'Handled by AHV'} )
app urls.py
from django.urls import path
from . import views
from .views import *
urlpatterns = [
path('', AjaxHandlerView.as_view() ),
path('ajaxg' , views.ajaxgtest, name="ajaxg" )
]
jquery ajax functions (ignore the post method)
var test_str = "[0,0]";
$(document).ready(function(){
var csrf = $('input[name=csrfmiddlewaretoken]').val()
$('#jq_btn').click(function(){
$.ajax({
url: '',
type: 'get',
data: {
button_text: test_str
},
success: function(response) {
$("#jq_btn").text(response.test + test_str);
console.log(test_str);
}
});
});
$('#post_btn').click(function() {
$.ajax({
url: '',
type: 'post',
data: {
text: test_str,
csrfmiddlewaretoken: csrf
},
success: function(reponse) {
test_str = reponse.postdata
console.log(test_str);
}
})
});
});
However I wanted to use a specific function for specific methods.. so I tried using a def..
views.py that is not working:
def ajaxgtest(self, request):
text = request.GET.get('button_text')
print(text + "deffer")
if request.is_ajax():
return JsonResponse({'test': 'blah'})
return render(request,'home.html' , {'name': 'Handled by AHV'} )
As for the Jquery code, all I did was edit url: '' to url: 'ajaxg' (which is what I named the view in the urls.py file)
new jq ajax code:
$('#jq_btn').click(function(){
$.ajax({
url: 'ajaxg',
type: 'get',
data: {
button_text: test_str
},
success: function(response) {
$("#jq_btn").text(response.test + test_str);
console.log(test_str);
}
});
});
I'm getting the error code;
TypeError: ajaxgtest() missing 1 required positional argument: 'request'
[01/Jan/2021 01:25:31] "GET /ajaxg?button_text=%5B0%2C0%5D HTTP/1.1" 500 58077
I'm unsure where I need to put a request element, or what not..

Related

Django: ajax not returning or sending any data in django

i am creating a simple like button with ajax, i have followed the tutorial but it seems, that i am missing something, i am not getting any error either in the console in my django terminal but when i click the button no data get sent, evrything just remains the same way, and this is not what i am expecting, i know i am missing something somewhere and i cannot really tell where this error is coming from.
views.py
#login_required
def like(request):
if request.POST.get("action") == 'post':
result = ""
id = int(request.POST.get('courseid'))
course = get_object_or_404(Course, id=id)
if course.like.filter(id=request.user.id).exists():
course.like.remove(request.user)
course.like_count -= 1
result = course.like_count
course.save()
else:
course.like.add(request.user)
course.like_count += 1
result = course.like_count
course.save()
return JsonResponse({'result': result})
urls.py NOTE:I don't know if i need a slug in this url path
path('like/', views.like, name="like"),
base.html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
course-detail.html
<li><button id="like-button" value="{{course.id}}">like</button><span id="like-count">{{course.llke_count}}</span></li>
<script type="text/javascript">
$(document).on("click", '#like-button', function(e){
e.preventDefault()
$.ajax({
type: 'POST',
url: '{% url 'course:like' course.slug %}',
data: {
courseid: $('#like-button').val(),
csrfmiddlewaretoken: $("input[name=csrfmiddlewaretoken]").val(),
action: 'post'
},
success: function(json){
document.getElementById("like-count").innerHTML = json['result']
console.log(json)
},
error: function (xhr, errmsg, err)
console.log(xhr)
console.log(errmsg)
console.log(err)
})
})
</script>
this is all the code i have written for the functionality, if there is any other thing to be provided i will update the question
UPDATE AFTER FIRST ANSWER
#####################################################################
Now when i click the like button is does show an visible error but the like count now shows undefined and in my chrome dev tools is shows failed to load response data because this request was redirected
Update your code like this and I've doubt about your like table provide that inside your question.
inside your views.py
#login_required
def like(request):
if request.method == 'POST':
result = ""
course_id = int(request.POST.get('courseid'))
course = get_object_or_404(Course, id=course_id)
if course.like.filter(id=request.user.id).exists():
course.like.remove(request.user)
course.like_count -= 1
result = course.like_count
course.save()
else:
course.like.add(request.user)
course.like_count += 1
result = course.like_count
course.save()
return JsonResponse({'result': result})
inside your course-detail.html
<script type="text/javascript">
$("#like-button").on("click", function (e) {
e.preventDefault()
$.ajax({
type: 'POST',
url: "{% url 'course:like' %}",
data: {
courseid: $('#like-button').val(),
csrfmiddlewaretoken: "{{ csrf_token }}",
},
success: function (json) {
document.getElementById("like-count").innerHTML = json['result']
console.log(json)
},
error: function (xhr, errmsg, err) {
console.log(xhr)
console.log(errmsg)
console.log(err)
}
})
})
</script>
Note :
You don't have to check for action instead you can check for method eg. request.method.
You've provided wrong url inside your ajax call '{% url 'course:like' course.slug %}' it should be '{% url 'course:like' %}' without passing slug.
Do not use id as avariable because it will conflict with python id() function, you can check for all available built-in functions in python here.

Error trying to save data in django via ajax(fetch)

I have a model that references other models, I am trying to save data using ajax
Example:
class Friend(models.Model):
name = ...
class Main(models.Model):
name = ....
friend = models.ForeignKey(Friend, on_delete=models.CASCADE)
All body comes from ajax(fetch) request
I have a table (html), and add data to cells, then with the
enter event, send data.
Like this:
input.addEventListener("keyup", function (e) {
//in this scenario I already have the whole row
// get full_row `row_data`
post_ajax = {
method: "POST",
headers: {
"X-CSRFToken": crf_token, // I get it with a regular expression
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
Accept: "application/json",
},
body: JSON.stringify(row_data),
};
fetch("my_url", post_ajax)
.then((res) => res.json())
.catch((error) => console.error("Error:", error))
.then((response) => console.log("Success:", response));
});
My view function
def save_post(request):
if request.is_ajax and request.method == "POST":
body_unicode = request.body.decode('utf-8')
data = json.loads(body_unicode)
print('here the data arrives',data)
# here the data arrives {'name': 'Ale', 'friend_id': 22}
Main.objects.create(name=data['name'], friends=data['friend_id'])
return JsonResponse({"instance": data}, status=200)
return JsonResponse({"error": ""}, status=400)
This is the error
raise TypeError("%s() got an unexpected keyword argument '%s'" %
(cls.__name__, kwarg))
TypeError: Main() got an unexpected keyword argument 'Friends'
Any idea or suggestion?
EDIT:
When you are creating the Main object, try making the "friend" attribute an object, like this:
friend = Friend.objects.get(id=data['friend_id'])
Main.objects.create(name=data['name'], friend=friend)
Also, the main issue appears to be you are calling the column "friends" but it should be "friend" when you are creating the Main object.
This:
Main.objects.create(name=data['name'], friends=data['friend_id'])
Should be:
Main.objects.create(name=data['name'], friend=data['friend_id'])
PREVIOUS ANSWER:
Assuming you are using JQuery in the template to send an AJAX request, since you did not specify.
In your urls.py:
...
path('/api/post_friend/', post_friend_api, name="post_friend_api"),
...
In your template :
<script type="text/javascript">
$("#myBurron").click(function(){
var csrfToken = $( "input[name='csrfmiddlewaretoken']"); // assuming this is a form
var friend_name = $("#friend_name").val();
$.ajax({ url: '{% url 'post_friend_api' %}',
type: "POST",
dataType: "json",
data: {'friend':friend_name, 'csrfmiddlewaretoken':csrfToken.val()},
cache: false
}).done(function(data) {
if (data.result === true){
alert(data.message);
}
});
});
});
</script>
In your views.py:
from django.http import JsonResponse
def post_friend_api(request):
data = {}
if request.POST.get('friend', None) is not None:
friend_name = request.POST.get('post_note')
# save the object and indicate success
data['result'] = True
data['message'] = "Friend saved successfully"
...
if request.is_ajax():
return JsonResponse(data)
else:
return HttpResponseBadRequest()
When you are sending data via POST don't forget to pass along your CSRF token as in the example above. This assumes you have a form on the page you can get it from, otherwise you can use something like this to get it:
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 = 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;
}
var csrftoken = getCookie('csrftoken');
If you don't want to deal with the CSRF token, you can mark the view with the #csrf_exempt decorator and remove the 'csrfmiddlewaretoken' data element from the Ajax call in the template, but it may not be ideal or the most secure. An example of that:
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
#csrf_exempt()
def post_note_api(request):
...
If you post more details I can update my answer.

HttpResponseRedirect not working for deletion and page redirect on button click

I am trying to delete a job at the click of a button and redirect to a different page. The deletion works but the redirection does not. My code is as follows:
views.py:
#login_required
def delete_job(request):
job_id = request.GET['Jobid']
job = Job.objects.get(pk=job_id)
try:
job.delete()
#return render(request, 'main/communitypartner_dash.html', {'form':form,'job' : job})
#return redirect('user_dash')
return HttpResponseRedirect('main/communitypartner_dash.html')
#return HttpResponseRedirect(reverse('user_dash'))
#jobs = user.jobs.all()
#return render_to_response('main/communitypartner_dash.html')
except Exception as e:
return HttpResponse("deletion not successful")
#return render(request, 'main/communitypartner_dash.html', {'form':form,'job' : job})
url.py:
url(r'^job/job_delete/$', views.delete_job),
html:
<button type="button" class="btn btn-primary" onclick="doDelete()">Dissolve</button>
<script>
function doDelete(){
$.ajax({
url: '/job/job_delete/',
data: {
'csrfmiddlewaretoken': $('input[name="csrfmiddlewaretoken"]').val(),
'Jobid': {{job.id}}
},
dataType: 'json',
complete: function (response) {
// $('#status').html(response.responseText);
},
error: function () {
// $('#status').html('Bummer: there was an error!');
},
});
return false;
}
I tried all the ways that are commented out in the try section of views.py. Please help. Thanks
The following will work
from django.http import JsonResponse
# codes here
job.delete()
return JsonResponse({'url':'main/communitypartner_dash.html'}) # whatever the url is
# or return JsonResponse({'url':reverse('url_name',kwargs={"arg":arg})})
js
// codes here
complete: function (response) {
window.location.href = response.url
},
error: function () {
// $('#status').html('Bummer: there was an error!');
},

How is MultiValueDictKeyError and AttributeError related in Django here?

I have a function in Django that I am trying to solve from my previous question here. While trying out my own solutions, I have made significant updates but I encounter an error.
I'm trying this out right now:
def view_routes(request, query=None):
routes = None
if query is None:
routes = Route.objects.all()
else:
#View: Routes in Queried Boundary
if request.method == 'POST':
return HttpResponse("OK")
elif request.method == 'GET':
json_feature = json.loads(request.GET.get('geo_obj', False))
#json_feature = json.loads(request.GET['geo_obj'])
geom = make_geometry_from_feature(json_feature)
routes = Route.objects.filter(wkb_geometry__within=geom[0])
print("Total Routes Filtered: " + str(Route.objects.filter(wkb_geometry__within=geom[0]).count()))
#Render to Django View
routes_json = serialize('geojson', routes, fields=('route_type', 'route_long', 'route_id', 'wkb_geometry',))
routes_geojson = json.loads(routes_json)
routes_geojson.pop('crs', None)
routes_geojson = json.dumps(routes_geojson)
#return render(request, 'plexus/view_routes.html', {'routes':routes})
return redirect('routes_view', query)
I am having trouble switching/commenting out between these two lines:
json_feature = json.loads(request.GET.get('geo_obj', False))
json_feature = json.loads(request.GET['geo_obj'])
Both presents an error respectively:
TypeError: the JSON object must be str, not 'bool'
django.utils.datastructures.MultiValueDictKeyError: "'geo_obj'"
Edited function with AJAX inside:
function sendQueryData(url, query){
url =url.replace('query' , query);
if (query === ""){
alert("City Input Required");
}else{
if(geo_obj === null){
alert("Click Search Button...")
}else{
$.ajax({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
type: "GET",
url: url,
dataType: 'html',
data: {
'geo_obj' : JSON.stringify(geo_obj)
},
success: function(data){
alert(data);
window.location.href = url;
//var result = $('<div />').append(data).find('#list-group').html();
//$('#list-group').html(result);
},
error: function(xhr, textStatus, errorThrown) {
alert('Request Failed' + textStatus + ":" + errorThrown);
}
});
}
}
}
Try using json.loads(request.body) if you are passing raw JSON, request.GET['foo'] is for form-encoded data

django.urls.exceptions.NoReverseMatch: Reverse for 'equipmentCheck' not found. 'equipmentCheck' is not a valid view function or pattern name

When I am trying to pull the code from github n my server where python version is 3.4 and Django version is 1.6 it shows the error for NoReverseMatch: Reverse for 'equipmentCheck' not found. 'equipmentCheck' is not a valid view function or pattern name.
But the same code is running perfectly in pythonanywhere where I am using Python 3.6 and Django 1.11.4
In urls.py
url(r'^reservedequipment/check', views.equipmentCheck,
name='equipmentCheck'),
In views.py
def equipmentCheck(request):
pkk = request.GET.get('pkk')
pk = request.GET.get('pk')
start = request.GET.get('start')
end = request.GET.get('end')
d = DeviceUsage.objects.filter(equipment__pk=pk, start__lte=start,
end__gte=start, status=1)
if pkk:
d.exclude(pk=pkk)
result = {'ok': True}
if d:
result = {'ok': False}
return JsonResponse(result)
in template
<script>
$(document).ready(function() {
$('#check-form').on('submit', function(evt){
console.log($('input[name="valid"]').val());
if($('input[name="valid"]').val()==1){
return true;
}
evt.stopPropagation();
evt.preventDefault();
var elem=this;
$.ajax({
url: "{% url 'equipmentCheck' %}",
data: {
pkk: "{{ booking.pk }}",
pk: $('input[name="equipment"]').val(),
start: $('input[name="start"]').val(),
end: $('input[name="end"]').val()
},
success: function(e){
if(!e.ok){
if(confirm('Your reservation time is overlapping with
an existing reservation. Do you want to continue your reservation?')){
$('input[name="valid"]').val(1);
$(elem).submit();
}
}else{
$('input[name="valid"]').val(1);
$(elem).submit();
}
}
});
});

Categories