calling ajax function in views.py to get the data from database - django

I want to fetch data from the database. I am using ajax function to get it in the index.html. How should I call this ajax function to the views.py so i can display it in view. How should I attain it?
My codes:
index.html
<script type="text/javascript">
function submitData(){
// Get answer from the input element
var dt = document.getElementById("major1").value;
var dtt = document.getElementById("major2").value;
var dttt = document.getElementById("major3").value;
var dtttt = document.getElementById("major4").value;
var dttttt = document.getElementById("major5").value;
// add the url over here where you want to submit form .
var url = "{% url 'home' %}";
$.ajax({
url: url,
data: {
'major1': dt,
'major2': dtt,
'major3': dttt,
'major4': dtttt,
'major5': dttttt,
},
dataType: 'JSON',
success: function(data){
// show an alert message when form is submitted and it gets a response from the view where result is provided and if url is provided then redirect the user to that url.
alert(data.result);
if (data.url){
window.open(data.url, '_self');
}
}
});
}
</script>
views.py:
def home(request):
majors = Major.objects.filter(percentages__isnull=False).distinct().order_by("pk")
if request.method == 'POST':
form = request.POST.get('be_nextyr_total')
line_chart = pygal.Line(width=1500)
line_chart.title = 'Budget Estimation'
context = {
"chart": line_chart.render_data_uri(),
'majors': majors
}
return render(request, "website/index.html" , context )

If you are doing a post request with Ajax, then you have to write in your ajax code like
type: "POST",
if you want to access your form data in view than you have to write
request.POST.get('your_variable_name_like_major1')

Related

Navigating to different page instead of Ajax call

I am trying to save a form via ajax as I don't want to reload the page. It is working not completely but it is updating the data except the image or video or any upload file we give.
but after updating it is coming back to the ajax page but the url is diiferent and success message is coming on that page.
I am sharing some of the logic but if more information is required, please let me know .
js code :
$(document).ready(function() {
$('#contentdataform').submit(function(e) {
e.preventDefault();
$.ajax({ // create an AJAX call...
data: $(this).serialize(),
type: 'POST',
url: 'updatecontent',
success: function() {
mess("Success"); //mess is a function to generate a disappearing message box.
},
});
return false;
});
});
function updatecontentform(){
console.log('starting');
document.getElementById('contentdataform').submit();
}
views.py
#csrf_exempt
def updatecontent(request):
print("--------------------")
if request.method == "POST":
id = request.session['content_id']
fm = ContentForm(request.POST, instance= Content.objects.get(pk = id))
print("fm")
print(fm)
if fm.is_valid:
print("valid form")
form = fm.save(commit=False)
form.save()
else:
print("Not Valid")
return JsonResponse("Success", safe= False)
the output should be the message on the same page but it is reflecting on the new page with url '127.0.0.1:8000/updatecontent'

Show loading gif until the django view performs the data processing and renders the template with this data

I have a django project where the page has multiple nav links representing different agents. On clicking any nav link, the urls.py redirects to nav specific view and the view needs to perform some processing to get the data needed to render the template. However as this is syncrhonous rendering it takes a long while to load data (in the order of 15-20s).
Below is my urls.py:
from django.urls import path
from . import views
app_name = 'agent'
urlpatterns = [
path('agent1/', views.agent1, name='agent1'),
path('agent2/', views.agent2, name='agent2'),
path('agent3/', views.agent3, name='agent3'),
path('agent4/', views.agent4, name='agent4'),
]
My views method looks as below:
def agent1(request):
agent_data = Agent1.objects.all()
agent_details = get_agent_details(agent_data)
return render(request, 'manager/data.html', {'agent_data': agent_data, 'agent_details': agent_details})
I am using the {{ agent_data.name }}, {{ agent_data.code }}, {{ agent_data.qty }} and {{ agent_data.price }} along with data from agent_details dictionary in my html to populate a table's rows. How should I change my view method, so that it loads the data via AJAX (javascript) in order to show a loading gif in the meantime and also provide me the data so that I can populate the table. Could someone help me with the Ajax code and the steps as I am new to this technology and not finding any help going through the online tutorials.
So for this to work with ajax, you'll need some javascript in manager/data.html which knows the url to fetch data from.
As an example, I've got an ajax setup which checks a given email address isn't already in use;
(function($) {
$(document).ready(function() {
var validateEmailURL = $section_user_signup.data('ajax-email-url');
function validateEmailUnique() {
var valid = true;
clearError($email);
// Fetch unique status of the provided email
$.ajax({
async: false,
url: validateEmailURL,
method: 'POST',
type: 'POST',
dataType: 'json',
data: {
'email': $email.val(),
'csrftoken': $form.find('input[name="csrfmiddlewaretoken"]').val()
},
success: function (response) {
valid = true;
},
error: function (response) {
setError($email, response["responseJSON"]["error"]);
valid = false;
}
});
return valid;
}
});
})(window.jQuery);
This javascript uses the data attribute of a div for the URL to check;
<div data-ajax-email-url="{% url 'account_ajax_validate_email' %}">
The view which the ajax call goes to looks like this;
def ajax_check_email_unique(request, *args, **kwargs):
"""
Return an JsonResponse to identify if an email is unique.
"""
if not request.is_ajax():
return HttpResponseBadRequest()
if request.is_ajax and request.method == "POST":
email = request.POST.get('email')
if email_address_exists(email):
return JsonResponse(
{
"error":
"Email address already exists. Click "
f"here "
"to login"
},
status=400
)
return JsonResponse(
{"email": email},
status=200
)
# some error occurred
return JsonResponse({"error": ""}, status=400)
The important thing for any view which will be used by javascript is that you return a JsonResponse.
So if I was you, I'd setup a new view for ajax, and that makes your existing one really simple;
def agent1_ajax(request):
agent_data = Agent1.objects.all()
agent_details = get_agent_details(agent_data)
return JsonResponse({
"agent_data": agent_data, "agent_details": agent_details
}, status=200)
def agent1(request):
return render(request, 'manager/data.html', {})
And as far as a loading gif goes, you'd need an element that contains the gif and then you can bind to the ajax event to show/hide;
$(document).ajaxStart(function() {
$("#loading").show();
});
$(document).ajaxStop(function() {
$("#loading").hide();
});

Django: send array with AJAX

I want to send an array of values via AJAX to a Django view but I only find how to send forms.
For example I send the following array of values. How do I access that array in my views?
Let to_save = []
$.each($('.linea_producto').find('.esta_coleccion.elegido'), function(index, value) {
producto = $(this).find('.producto').text();
marca = $(this).find('.marca').text();
packaging = $(this).find('.packaging').text();
categoria = $(this).find('.categoria ').text();
to_save.push({marca, producto, packaging, category});
});
$.ajax({
url:'/target_url/',
type:'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(to_save),
success:function(response){
},
error:function(){
},
});
Thanks in advance!
You can access the data you have sent in the body of your POST request via request.POST like so:
def my_view(request):
post_data = request.POST
# do something with post_data
request.POST will be a dictionary-like object.

Sending variable Client Side (JS Ajax) to Server Side (Python Django)

I am using Python 3.7.4 with Django 3.0.3 and I have a script Ajax in javascript run in the front end app. When the user click in link, a variable must to be sending to back end python. See the exemple
Javascript
$('.likebutton').click(function() {
var catid;
catid = $(this).attr("data-catid");
$.ajax({
type: "GET",
// url: "/likePost",
url: "/likePost/" + catid,
/* data: {
post_id: catid
},
*/
success: function(data) {
$('#like' + catid).remove();
$('#message').text(data);
}
})
});
urls.py
In the urlpattner of app I have
urlpatterns = [
path('', views.index, name='index'), # index view at /
path('likePost/', views.likePost, name='likepost'), # likepost view at /likepost
]
views.py
def likePost(request):
if request.method == 'GET':
post_id = request.GET['post_id']
likedpost = Post.obejcts.get(pk=post_id) #getting the liked posts
m = Like(post=likedpost) # Creating Like Object
m.save() # saving it to store in database
return HttpResponse("Success!") # Sending an success response
else:
return HttpResponse("Request method is not a GET")
In Debug I received the follow message error
Not Found: /likePost
[25/Feb/2020 16:12:17] "GET /likePost?post_id=1 HTTP/1.1" 404 2335
What I am doing wrong?
In your ajax script, you are passing a querystring parameter called post_id (eg. likePost/?post_id=1), but in your urlpatterns, you specify post_id as a path parameter (eg. likePost/1/).
You have 2 options:
post_id as a path parameter
Add the post_id to the url instead of sending it as data:
$('.likebutton').click(function() {
var catid;
catid = $(this).attr("data-catid");
$.ajax({
type: "GET",
// standard syntax
url: "/likePost/" + catid,
// template string syntax
// url: `/likePost/${catid}`,
success: function(data) {
$('#like' + catid).remove();
$('#message').text(data);
}
})
});
Then add post_id to your view:
def likePost(request, post_id):
...
post_id as a querystring
change your path to the following:
path('likePost/', views.likePost, name='likepost')
You can then access post_id via request.GET in your view:
def likePost(request):
post_id = request.GET['post_id']
...
Furthermore, I'd recommend reading When do I use path parameters vs. query params in a RESTful API? if you aren't sure of which option to use.

Updating only part of an HTML page using Django

I have an HTML (annotator.html) page where the top half contains a table. I have JavaScript code that pulls data out of the data model when the user selects a row in the table and displays that data in a div below the table.
My Javascript looks like this:
$('#radiological tbody').on( 'click', 'tr', function () {
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
}
else {
//first unselect any other selected row
dt_table.$('tr.selected').removeClass('selected');
//then select row of interest
$(this).addClass('selected');
var rowIndex = dt_table.row('.selected')[0];
var row = dt_table.rows(rowIndex);
var id = row.data()[0]['id'];
var url = '/report/' + id + '/';
//window.location = url;
$.ajax({
url: url,
type: 'get', // This is the default though, you don't actually need to always mention it
success: function(data) {
},
failure: function(data) {
alert('Got an error dude');
}
});
And correctly populates the bottom half of my page but also updates the top half. I Just want the bottom half refreshed.
My report view looks like this:
def report_page(request, id):
template_name = "annotator.html"
data = Radiology2.objects.get(id=id)
context = {"data": data}
context["title"] = title
context["version"] = version
context["id"] = id
if (request.is_ajax()):
# return render(request, template_name, context)
return JsonResponse(context)
else:
return render(request, template_name, context)
I added support for AJAX. I'm just not sure how to return from view properly when AJAX is used. Obviously, I'm not understanding something.
Instead of Ajax, I replaced window.location=url; with $('#divIdToRefresh').load(url + ' #divIdToRefresh');
You can easily use Ajax - jQuery or native JS would be better for that