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)
Related
I am working on a project that generates dynamic urls, For ex. if I type 127.0.0.1:8000/newpage it generates a new model with slug newpage
Earlier the project was working fine but suddenly it started to show some bugs.
I am calling a URL using ajax like this (5th line):
$(document).on('click', '#save', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url "text:update" %}',
data: {
newText: $('#text-content').val(),
slug: "{{ obj.slug }}",
csrfmiddlewaretoken: "{{csrf_token}}",
action: 'post'
},
success: function (json) {
if (json['status'] === 'OK') {
document.getElementById('msg-box').innerText = 'TEXT SAVED';
window.removeEventListener("beforeunload", beforeUnloadListener, { capture: true });
}
},
error: function (xhr, errmsg, err) {
}
});
});
It should load the view which I defined in the update url patterns but because of some reason it is still loading my slug view and generating a new url with slug update, I mean it shouldn't do that if I am telling it to load a specific view in URL pattern then why it is still loading slug view below is my urls.py:
#Only patterns
path('', home, name='home'),
path('<slug:slug>/', textview, name='textview'),
path('update/', update, name='update'),
views.py
def textview(request, slug):
obj, created= Text.objects.get_or_create(slug=slug, defaults={'text':'', 'password':'123'})
return render(request, 'text/textpage.html', {'obj' : obj, 'created' : created})
def update(request):
if request.POST.get('action') == 'post':
slug = request.POST.get('slug')
text = request.POST.get('newText')
obj = Text.objects.get(slug=slug)
obj.text = text
obj.save()
response = JsonResponse({'status':'OK','text':text})
return response
Where are you using this AJAX code? If it is in a JavaScript file (.js), Jinja won't work there, so you have to write the absolute URL or you have to define a variable for the Jinja in the HTML and then use that variable in the JS file.
And try to add a slash after the URL if your APPEND_SLASH not True in settings.py.
I'm developing a stock market app with a python flask framework.
The user has a route where he can see his details and the number of shares.
If a change in the user shares has occurred, I would like it to be displayed automatically. (Without the need for the user to refresh the page).
To make a long story short, I would like the '/user_page/<user_name>' route to refresh automatically when the '/update_page/' route is writing to the DB.
#app.route('/user_page/<user_name>', methods=['GET', 'POST'])
def user_page(user_name):
user = Users.query.filter_by(user_name=user_name).first()
return render_template('user_page.html', user=user)
#app.route('/update_page/<user_name>', methods=['GET', 'POST'])
def update_user_holdiongs(user_name):
if user_name.bid > last_bid:
change = TradeBids.query.filter_by(id=user_name.id).update(dict(share_amount=user_name.share_amount - bid.share_amount))
db.session.add(bid)
db.session.commit()
You can use AJAX to monitor changes on your backend and refresh (or rewrite) page. You need something like that:
setInterval(function() {
// AJAX send request
$.ajax({
url: "your url here",
type: "GET",
dataType: "json",
success: function (data) {
if (data.success) {
location.reload();
}
},
error: function (request, error) {}
});
}, 30000); // check about changes every 30 seconds
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()
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
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)