django ajax get model data in JS variable - django

Trying to get my model data from django views.py in home.html javascript variable using AJAX.
So far I'm at :
Views.py:
class HomePageView(ListView):
model = Flights
template_name = 'home.html'
def flights_list(request):
flights = serializers.serialize("json", Flights.objects.all())
return JsonResponse({"flights": flights})
Ajax:
function get_data() {
$.ajax({
url: '', //Not sure what to put here.
datatype: 'json',
type: 'GET',
success: function (data) {
alert("Got data!")
locations = {{ flights }};
}
});
};
$(document).ready(function(){
setInterval(get_data,5000);
});
Every 5 seconds i'm getting alert "Got data!"
But when I'm trying to pass variable location = {{ flights }};
Then locations is empty.
in ajax url:'' i suppose to have my views.py location? as when trying to alert("Got data!" + data) then my whole html is in that data variable..
Am i doing something wrong here?
UPDATE:
My flights urls:
from django.urls import path
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register(r'flights', views.FlightViewSet)
urlpatterns = [
path('',views.HomePageView.as_view(),name='home'),
]
Update 2:
Ok so I've found out what's wrong,
Changed urls.py:
urlpatterns = [
path('',views.HomePageView.as_view(),name='home'),
path('flights/', views.flightslist, name='flights')
]
Views.py:
def flightslist(request):
flights = serializers.serialize("json", Flights.objects.all())
return JsonResponse(flights, safe=False)
Had to add safe=False as no other way worked..
Update:
I've managed to sort it out by code:
function get_data() {
$.ajax({
url: 'flights/',
datatype: 'json',
type: 'GET',
success: function (data) {
alert("Got data!")
var locations = data;
}
});
};
$(document).ready(function(){
setInterval(get_data,5000);
});
How to convert var locations = data to dictionaries? As now it shows up as :
[{"model": "flightapp.flights", "pk": 390, "fields": and only then dictionary that i need.

Related

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();
});

Data from react axios post is not sending data to django

I am trying to send post data from react to django, however, the data is not attached to the post object. My react code looks something like this:
class Homepage extends React.Component {
createProject() {
axios({
method: "post",
url: "localhost:8000/createProject/,
headers: { "Content-Type": "application/json" },
data: { name: "projectname" },
})
}
render() {
return <div onClick={this.createProject}></div>
}
urls.py
urlpatterns = [
path( "createProject/", views.createProject ),
]
views.py
def createProject( requests ):
print( requests.POST )
return JsonResponse({"this returns": "just fine"})
output from print( requests.POST ) in views.py:
<QueryDict: {}>
If it matters, I'm using csrf_exempt on my django functions as there are no plans of deploying.
Thanks!
Try to print in the view
print(request.get.POST('data'))

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.

Django: combining method and class inside views to share same url

I'm working on Django project where I have an app which has a page with a drop down and a chart that is generated from data (which is queried from the database and passed into an API url). I'm using class based views and APIView and have a get method which is creating a response to pass some Json data into a url. I have the following class in my views.py set up and working.
views.py
class ChartData(APIView):
authentication_classes = []
permission_classes = []
def get(self, request, format=None):
#generated through code
data = {
"labels": all_times,
"default": all_data,
}
return Response(data)
In order have access to this data, I have my url set as:
url(r'^display/api/chart/data/$', views.ChartData.as_view()),
This data from the API is used to generate a ChartJS graph in my template html of this app. The chart is set up so that it seeks the Json data from the url display/api/chart/data/ and uses Ajax to populate itself. Here is how the chart is generated:
<script>
{% block jquery %}
var endpoint = 'display/api/chart/data/'
var defaultData = []
var defaultLabels = [];
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
defaultLabels = data.labels
defaultData = data.default
console.log(data)
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: defaultLabels,
datasets: [{
label: '# Measurable',
data: defaultData,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
{% endblock %}
</script>
I also have another method in the same views file as follows:
views.py
def DropdownDisplay(request):
items= #query from database
if (request.method == 'POST' and request.is_ajax()):
print(request.POST)
return render(request, 'DisplayData/Display.html',{'dropdown':items})
This method is used to generate a dropdown in the page. The url for this is set up in the same urls.py file as follows:
url(r'^graph/', views.DropdownDisplay, name='Display-Dropdown')
Note: they are in the same views.py and urls.py file, I just separated them in this post for formatting purposes.
Now, I'm running into an issue. When I go to /display, the graph works, but the drop down does not. When I go to /display/graph, the drop down works but the graph does not. I can tell it is because in my urls.py, I have separate urls for each class and method, so they only work under their respective url.
However, I would like to combine them so that both the generation of the graph, and the population of the dropdown, work under one url, which will be /display.
How can I go about achieving this?
If you want them to be a part of the same page, both the functionalities should be inside a form under one view. If not, there should not be one single url for two separate functionalities. Your question is a bit ambiguous. If you can clearly state the functionality, would be helpful.

Django - retrieve form data

I am trying to send a form through ajax call to django view as follows:
$.ajax({
type: 'POST',
url: "{% url 'edit_experience' %}",
data: {
item_id : itemId,
form: $("#sample-form").serialize()
},
beforeSend : function() {
},
success: function (data) {
},
error: function(data) {
},
complete : function() {
}
});
I am able to see the data being posted to the http server:
form role=Fresher&organization=TestOrganization&description=Hard+work+pays
item_id 3
My problem is in the server side where I am trying to fetch the data. I am able to access the item_id but I am having a problem accessing the form elements:
In Django View:
def edit_experience(request):
request.POST['form']['role']
return ....
This does not fetch the role. What is the correct way to fetch all the form attributes??
Kindly help. Thanks in advance.
To fetch attributes from the querystring you can use QueryDict:
from django.http import QueryDict
d = QueryDict(request.POST['form'])
role = d['role']