Pass data from Django view to template - python

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)

Related

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

Django Ajax Call and response with Render

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

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)

Django redirects - how to handle redirect when using ajax

I need return redirect(url) or something like this in django, and force template to do to this url.
It returns me template html-code instead when EXACTLY redirect is required.
Any ideas? Now i have to write redirect in templates window.location='url' , it works, but make code tangled.
django.__version__ == '2.0.1'
I need django text, that does like javascript window.location='myurl'
Part of view
#csrf_exempt
def CheckState(request):
...
try:
... if (condition):
a = redirect('/mypage/')
...
return a #redirect('http://localhost:port/mypage/')
part of template (js.code)
$(document).ready(function() {
$.get('/my/CheckState/', {})
.success(function(data){
console.log(data);
//window.location = 'url' works here, otherwice no redirect!
//In console i see html-code of 'http://localhost:port/mypage/'
})
.error(function(xhr, textStatus, errorThrown){
console.log(xhr.responseText);
})
--comment--
a._headers = {'content-type': ('Content-Type': 'text/html; charset=utf-8'),
'location' : ('Location', '/mypage' )}
I saw this header before i asked question, but problem exists - no jump doing. Why is this redirect not working?
It's not possible to prevent $.get() (which uses Xmlhttprequest) from following the redirect. See this question for an explanation.
You might be able to use the fetch API which does allow you to prevent redirects.
If you can't do that, you could change the view to return the new URL in the response,
from django.http import JsonResponse
def CheckState(request):
return JsonResponse({'status': 'redirect', 'url': '/new/url/'})
...
Then in your ajax handler, check the response for status=redirect, and if so set window.location to the url.

Unable to receive json response from Django view to template?

I am trying to send a json response from django view to template but when I try to console.log the response in my ajax, I am getting nothing. What could i be doing wrong ? I am trying to pass the result data from views to my ajax success function. I also noticed something strange that when I mention the datatype = json in my ajax then I dont receive any response in the success function but when I remove the dataType = json then I get the entire html of my template in my success function as a response. Why is that ??
views.py
class ChangePassword(View):
def post(self, request, *args, **kwargs):
form = PasswordChangeForm(request.POST)
#current_password = json.loads(get_value.current_password)
#print ('current password',get_value['current_password'])
if form.is_valid():
print("valid form")
user = CustomUser.objects.get(email=request.user.email)
current_password = form.cleaned_data['current_password']
print('current_password',current_password)
new_password = form.cleaned_data['new_password']
print('newpassword',new_password)
if user.check_password(current_password):
print('entered')
update_session_auth_hash(self.request, self.request.user) # Important!
user.set_password(new_password)
user.save()
result = {'success': "Succefully reset your password"};
result = json.dumps(result)
print ('result',result)
return render(request, 'change_password.html',context={'result': result})
else:
return render(request, 'change_password.html', {'error': "We were unable to match you old password"
" with the one we have. <br>"
"Please ensure you are entering your correct password"
"then try again."})
else:
print("not valid")
return render(request, 'change_password.html', {'form':form})
def get(self, request, *args, **kwargs):
return render(request, 'change_password.html', {})
template
function changePassword() {
csrfSetUP()
new_pass = document.getElementById('new_pass')
cur_pass = document.getElementById('current_pass')
if (validpassword(new_pass) && cur_pass!= "") {
var cpass = $('#current_password').val();
var npass = $('#new_pass').val();
var data = {current_password:cpass,new_password:npass}
$.ajax({
url: '/account/change_password/',
type: 'post',
data: data,
dataType: "json",
success: function(json) {
console.log(json)
}
});
} else {
$('#change_password').submit()
}
}
When you are working with AJAX you have to use JSONResponse() instead of render()
from django.http import JsonResponse
return JsonResponse({'foo':'bar'})
If you need to have generated some HTML with that JSON - it is even better to use render_to_string method and return a html string to your AJAX, smth like that:
html = render_to_string('ajax/product_details.html', {"most_visited": most_visited_prods})
return HttpResponse(html)
NOTE: When using render_to_string remember to delete dataType: "json" from your AJAX, cuz u return not JSON, but a string.
P.S. Under this question there are plenty of examples how this can be done, but look at newer ones.

Categories

Resources