Django Ajax Call and response with Render - python

I am new to Python and Django and I would like to do a task where the user have 2 drop downs. Item drop down and Machine drop down. The Machine drop down is filled depending on the selection of the Item drop down and at the same time a table is refreshed depending on the selection of the 2 drop downs.
I was thinking to do so, from JavaScript, onChange of Item drop down, I use an AJAX function which calls a function in view.py by providing Item selection as show in the Javascript part. On return of the Django function I use render return.
Both the JavaScript and def load_machines seems to work fine but the return render(request, 'home.html', {'machines': machines}) is calling home.html but machines is empty.
How shall I tackle such problem, any hint what to look at?
JavaScript part
<script>
$("#exampleFormControlSelect1").change(function () {
const url = $("#mainForm").attr("data-machines-url");
const itemId = $(this).val();
$.ajax({ // initialize an AJAX request
url: url,
data: {
'itemId': itemId // add the item id to the GET parameters
},
success: function (data) { // `data` is the return of the `load_cities` view function
}
});
});
</script>
Django Part
view.py
def load_machines(request):
item = request.GET.get('itemId')
machines = List.objects.filter(item=item).all()
print(machines) // working FINE
return render(request, 'home.html', {'machines': machines})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name ='home'),
path('ajax/load-machines/', views.load_machines, name='ajax_load_machines')
# AJAX
]

rather than using render
return render(request, 'home.html', {'machines': machines})
you should return JsonResponse
from django.http import JsonResponse
data = {'machines': machines}
return JsonResponse(data)
doc about JsonResponse is here. You can also check out some simple tutorials like this

Related

Getting TypeError when trying to use Django and Pandas to show data in html

import pandas as pd
from django.shortcuts import render
# Create your views here.
def home():
data = pd.read_csv("\\pandadjangoproject\\nmdata.csv", nrows=11)
only_city = data[['name']]
context = {
"data": data.to_html(index=False),
"only_city": only_city.to_html()
}
return request(render, 'home.html', context)
#Here is my HTML Page
<html>
<head>
<title>NM Biggest citys</title>
</head>
<body>
<h1>New Mexicos Largest Citys</h1>
{{only_city|safe}}
</body>
</html>
#I get this error:
TypeError at /
home() takes 0 positional arguments but 1 was given
Request Method: GET
Request URL: http://localhost:8000/
Django Version: 4.0.1
Exception Type: TypeError
Exception Value:
home() takes 0 positional arguments but 1 was given
Looks like the Problem was actually with my csv file it was somehow empty when i copied it from another csv file so i got the original and put it in my django folder with drag and drop.
The other problem i did have was in my view I accidently had return request(render but in django its supposed to be return render(request,
A view function, or view for short, is a Python function that takes a web request and returns a web response.
Add request in your home as
def home(request):
data = pd.read_csv("\\pandadjangoproject\\nmdata.csv", nrows=11)
only_city = data[['name']]
context = {
"data": data.to_html(index=False),
"only_city": only_city.to_html()
}
return render(request, 'home.html', context)

Unable to render a template after using fetch in django

I have the following requirement:
Send data to backend using fetch()
receive the data in a view and render another template ( route to a different view)
The following is my code snippet:
JS:
fetch("/addpost", {
method: "POST",
body: JSON.stringify({ value: selecteddict }),
headers: {
"Content-type": "application/json;",
},
})
.then((res) => {
return res.text();
})
.then((text) => {
console.log(text);
});
// the data is being sent successfully
Django View1:
#csrf_exempt
def addpost(request):
if request.method == 'POST':
song = json.loads(request.body.decode('utf-8'))['value']
print(song)
# I want to redirect to another view called createpost that renders a new page
return JsonResponse({'status':201})
return render(request, 'addpost.html')
Django createpost view:
def createpost(request):
return render(request, 'createpost.html')
The view createpost is working fine when given the required path but it is not rendering when it's redirected from addpost
Please suggest a solution to this.
Your addpost view returns as JsonResponse in case of a POST request. If you want to redirect somewhere you need to use redirect() instead of JsonResponse()

How to redirect from payment page to index page

After payment, I have redirected it to the success page.
form action="success" method="POST"
Views tab
def success(request):
return render(request, 'success.html')
Now I want the page to automatically redirect to the index/home page after a small delay.
How can that be achieved. Can anyone please help with this?
Instead of return render(request, 'success.html'), use return redirect('index') where index is name of the url of index. Make sure, in urls.py , there is a url for index, path('index',views.index,name='index')
I think you could achieve this by using setTimeout and window.location.href in javascript.
using time.sleep is another option here, but this will make the request stop for seconds, and this may raise request timeout.
success
def success(request):
return render(request, 'success.html')
success.html
<script>
function redirect () {
var x = setTimeout(function () {
window.location.href = "{% url 'index' %}";
window.clearTimeout(x); // clear time out.
}, 5000);
</script>

Pass data from Django view to template

I have a very basic view that is supposed to render a page and pass some data to this page, here is how i do it:
def myview(request):
request = mydb.objects.filter(user=request.user)
return render(request,
"main/mytemplate.html",
context={"data":request})
When the page is loaded, the data is passed to the template, so to show that data, i'll only have to go to my html and add this:
{{data}}
But how can i do the same from a view that is not the same view that renders the page?
Let's say that this is a view that i can call with an Ajax request, so when the Ajax request is triggered, the view should send data in the same way and i want to be able to use it in the Django template language.
Here is an example:
def secondview(request):
request = mydb.objects.filter(item='free')
return HttpResponse(request)
This view is called from an Ajax request, it will send a response with the data, but i don't want to get the data in this format or in json format, instead i want to use it from the Django template language, just as i did with the first example. Is there any way to do it? Or can i only pass data to the template in the context?
1) Instead of returning HttpResponse in your secondview do this
def secondview(request):
from django.template.loader import render_to_string
x = 1
return render_to_string('template_name.jinja', locals())
2) If you want to display that response in your html, do this in your html,
<div id="x"> </div>
function someFunc(){
$.ajax({
url: "someurl",
type: 'GET',
success: function (response) {
document.getElementById("x").innerHtml = response
},
error: function (xhr, err) {
console.log(xhr.responseText);
},
cache: false,
contentType: false,
processData: false
});
I hope I've answered all of your questions, if not let me know.
def myview(request):
request = mydb.objects.filter(user=request.user)
context = {"data":request}
return render(request, "main/mytemplate.html", context)

Django render loading page then load actual page

My actual page that I want to load takes quite a bit of time because it querying an API for a lot of data (python is doing the backend querying). How can I render my loading page and then render my actual page when the data has been gathered.
What I am trying to do in my view.py
class Page(ListView):
def loading(request):
return render(request,'loading.html')
def viewProfile(request, player_name):
Page.loading(request)
context = {
'data1' : query_api(1),
'data2' : query_api(2),
'data3' : query_api(3),
}
return render(request, 'actualpage.html', context)
In your loading page, make an ajax request to the view which will query the api, and in the success callback set the html data in your template.
However, if the api takes a lot of time, I would suggest you to use celery for processing it asynchronously so that your user can navigate the website normally instead of waiting.
In your template -
$.ajax({
url: "<query_view_url>",
type: "GET",
dataType: 'json',
success: function (data){
$("#div_id").html(data.query_data);
},
error: function(e){
console.log(e);
}
});
In your views.py -
def view_of_query_url(request, <other parameters>):
<query_logic>
data = dict()
data['query_data'] = <your_queried_data> # In html format using render_to_string
return JsonResponse(data)

Categories

Resources