Currently I am loading my html page like as follow-
def home(request):
context = {}
template = 'home.html'
return render(request,template,context)
def about(request):
context = {}
template = 'about.html'
return render(request,template,context)
If i want to load using ajax then how i request for get. please help
If you want to GET request using ajax::
from django.shortcuts import render
def about(request):
if request.GET.get('id'):
data = request.GET.get('id', '')
template = loader.get_template('YourApp/about.html')
context = {
'data': data,
}
return HttpResponse(template.render(context, request))
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'data', views.about, name='about'),
]
Path for template should be ::
YourAPP/templates/YourApp/about.html
about.html
{% if data %}
{{ data }}
{% endif %}
hope, it helps !!
Related
I am using https://github.com/gmrchk/swup in combination with Twig/Timber. It works great, however, I have realised that none of my if clauses work whenever I get to a new page, since SWUP can't read the if arguments from my twig files. (it is a JS library to load pages dynamically)
For example:
{% if fn('is_single') %}
<div class="progress"></div>
{% endif %}
wouldn't load at all when I initially load the page on a not single-post page.
My idea was to re-render header.twig (where the above mentioned if clause is) with an AJAX call.
The AJAX call looks like that:
function swupReplaceHeader() {
jQuery.ajax({
type: "POST",
url: "/wp-admin/admin-ajax.php",
data: {
action: 'spx_replace_header',
},
success: function (output) {
console.log(output);
}
});
}
swupReplaceHeader();
document.addEventListener('swup:clickLink', swupReplaceHeader);
It is wrapped inside an event listener that fires every time I click on a link.
The WP function looks like that:
add_action('wp_ajax_spx_replace_header', 'spx_replace_header');
add_action('wp_ajax_nopriv_spx_replace_header', 'spx_replace_header');
function spx_replace_header()
{
$context = Timber::get_context();
Timber::render('templates/header.twig', $context);
wp_send_json_success(['AJAX is working']);
}
I added the send JSON message to test if my AJAX call is working.
Now, whenever I test the AJAX call without the Timber code it is working, but when I add the two Timber lines to the function, nothing happens - not even the JSON message appears. I tried Timber::compile as well without any luck.
I hope someone can help me..
Best,
Dennis
Answer posted by aj-adl on Github:
Hey Dennis,
You're making a call to wp-admin/admin-ajax.php, so conditionals like is_ajax() will return true but is_single() will definitely not.
Remember that PHP shuts down at the end of each request, discarding state etc, so the call to the admin-ajax.php script is a completely isolated process from the one that's delivered the initial markup for the page, and doesn't know what page it's being called from etc
For this reason, you'd want to pass in any data you'd need for conditionals, probably as a query string parameter.
PHP:
add_action('wp_ajax_nopriv_spx_replace_header', 'spx_replace_header');
function spx_safe_get_string( $key )
{
if ( ! isset( $_GET[ $key ] ) ) return '';
return sanitize_text_field( $_GET[ $key ] );
}
function spx_replace_header()
{
$context = Timber::get_context();
// Set this in the context, so we can access it in our twig file easily
$context[ 'type' ] = spx_safe_get( 'my_page_type' );
Timber::render('templates/header.twig', $context);
}
JS:
window.addEventListener('load', function() {
jQuery.ajax({
type: "POST",
url: "/wp-admin/admin-ajax.php",
data: {
action: 'spx_replace_header',
my_page_type: 'single',
},
success: function (data) {
console.log(data);
}
});
})
Twig:
{% embed "objects/header.twig" with {'hamburger': 'hamburger--spring'} %}
{% endembed %}
{% if type == 'single' %}
<div class="progress"></div>
{% endif %}
{% embed "objects/header.twig" with {'id': '--sticky', 'hamburger': 'hamburger--spring'} %}
{% endembed %}
In django, I am trying to make buttons that change one segment of the webpage by loading html file. The html file shows map and statistics and stuff so they have to be separate.
My approach was to use ajax call and in the view, return the html file.
<script type="text/javascript" >
function mapcall (office, year){
console.log(office, year, "clicked")
$.ajax ({
method : "GET",
url: '/map/', // % url "map" % end point
data: {
office_called: office,
year_called: year,
},
success: function (map){
console.log("map is here ", map)
$("#maparea").load($( "{% static 'my_html_return' %}"
))},
error: function (error_data){
alert("data error, sorry")
}
})
}
</script>
<div id="maparea">
{% if map_return %}
{% with map_template=map_return|stringformat:"s"|add:".html" %}
{% include "mypath/"|add:map_template %}
{% endwith %}
{% endif %}
</div>
This is my view.py
def get_map (request, *args, **kwargs):
year = request.GET.get("year_called")
office = request.GET.get("office_called")
map_return = "map"+str(year)+office
return render(request, "mypath/home.html",
{"title": "Home", "map_return":map_return})
I don't know how to make this work. Any suggestion is appreciated.
I figured out that I needed to do .html(take html return from ajax as an argument) instead of .load in my case.
I hope this helps other people.
I want to pass two variable: scenario_name and scenario_id from my view to my ajax function in the html code.
So basically in the database, each Organization can have multiple scenarios. The organization and scenario models have 2 fields each: an id field and a name field.
And my other doubt is, once I pass it to ajax, how do I access the variables passed?
my views.py
from django.shortcuts import render, redirect
from Organization.models import Organization
from django.http import HttpResponse
from Scenario.models import Scenario
import json
from django.core import serializers
def alertindex(request):
return render(request, 'alertindex.html', {
'Organization': Organization.objects.all(),
})
def get_scenario(request):
org_id = request.GET.get('org_id')
organization = Organization.objects.get(pk=int(org_id))
scenario = organization.scenario_set.all()
scenarios = serializers.serialize("json", scenario)
return scenarios
urls.py
from . import views
from django.conf.urls import url
urlpatterns = [
# Add alert url
url(r'^$', views.alertindex, name='alertindex'),
# Bind data in scenario drop down
url(r'^/Scenario$', views.get_scenario, name='Get_Scenario'),
]
my ajax function
var orgID = $(this).val();
var scenarios = '{{ scenarios }}'
$.ajax({
type: "GET",
url: "{% url 'Get_Scenario' %}",
data: { org_id: orgID},
success: function () {
var udata = "";
for (var i = 0; i < scenarios.length; i++) {
udata = udata + "<option value='"+ scenarios[i].scenario_id + "'>" + scenarios[i].scenario_name + "</option>"
$("#txtScenario").append(udata);
}
},
});
The url Get_Scenario links me to my view having the function get_scenario.
The error that I am facing is " str' object has no attribute 'get' "
Traceback:
File "/Users/anirudhchakravarthy/anaconda3/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/Users/anirudhchakravarthy/anaconda3/lib/python3.6/site-packages/django/utils/deprecation.py", line 97, in call
response = self.process_response(request, response)
File "/Users/anirudhchakravarthy/anaconda3/lib/python3.6/site-packages/django/middleware/clickjacking.py", line 26, in process_response
if response.get('X-Frame-Options') is not None:
AttributeError: 'str' object has no attribute 'get'
Any help will be greatly appreciated.
You can use JsonResponse. Here's sample code.
(It's better to check try/exception and send 404 when not found object)
from django.http import JsonResponse
def get_scenario(request):
org_id = request.GET.get('org_id')
# you can do your own validation
try:
organization = Organization.objects.get(pk=int(org_id))
scenario = organization.scenario_set.all()
scenarios = serializers.serialize("json", scenario)
except ObjectDoesNotExist:
data = {
'result': 'fail',
}
return JsonResponse(status=404, data)
data = {
"scenarios": scenarios,
# add more data you want
}
return JsonResponse(data)
For more information about JsonResponse, just check here
Hello im trying to fill the field "amount" that cointains the price of the payment_plan, and the payment_plan is part of the client information. I've been searching and the way to do it is implementing Ajax, but i have not found an example with django forms, every solution is really diferent from mine.
this is the model:
class Payment_Plans(models.Model):
name = models.CharField(max_length=20, primary_key=True)
price = models.IntegerField(default='0')
def __unicode__(self):
return self.name
class Clients(models.Model):
id = models.IntegerField(max_length=10, primary_key=True, default=0)
payment_plan = models.ForeignKey(Payment_Plans, null=True)
def __unicode__(self):
return self.id
class Payments(models.Model):
client = models.ForeignKey(Clients)
month_from = models.DateField(default='1111-01-01')
month_to = models.DateField(default='1111-01-01')
amount = models.IntegerField(default='0')
def __unicode__(self):
return self.month_from.strftime('%Y-%m-%d')
this is my payment form:
class PaymentsForm(forms.ModelForm):
month_from = forms.DateField(widget=DateTimePicker(options={"format": "YYYY-MM-DD", "pickTime": False}), label="Mes desde")
month_to = forms.DateField(widget=DateTimePicker(options={"format": "YYYY-MM-DD", "pickTime": False}), label="Mes Hasta")
amount = forms.IntegerField(label="Monto")
client = forms.ModelChoiceField(queryset=Clients.objects.all(), label="Cliente")
class Meta:
model=Payments
fields = ('month_from', 'month_to', 'amount', 'client')
This is the template:
{% extends 'base.html' %}
{% load bootstrap %}
{% block titulo %}Realizar Pago{% endblock%}
{% block encabezado %}
<h1>Realizar Pago</h1>
<!-- Para el datepicker -->
{{ form.media }}
{% endblock%}
{% block contenido %}
<form id='form' method='POST' action=''>{% csrf_token %}
<div class="col-sm-4">
</div>
<div class="col-sm-4">
{{ form.client|bootstrap }}
{{ form.month_from|bootstrap }}
{{ form.month_to|bootstrap }}
{{ form.amount|bootstrap }}
{{ form.days_left|bootstrap }}
<input type='submit' name='submit' value='Pagar' class="btn btn-default"/>
</div>
</form>
{% endblock%}
this should work like this:
1) the user selects the Client (right now its just a select box, in future autocomplete field)
2) the form should look into the client's payment_plan and then into the payment_plan price.
3) field should be filled with the price
how can i achive this? is it possible with django forms? shall i write manually the template instead of ussing tags like {{forms.client}}? if thats the case, how do i get the Clients?
You can use AJAX, you just need to know the fields' ids. Set an onchange (or .change() if you're using jquery) event on the 'client' field that sends the client id to a view, for instance, '/client-price' that will use it to query for the other price. Something like:
$( "#client" ).change(function() {
clientID = $(this).val();
$.ajax({
type: "GET", // if you choose to use a get, could be a post
url: "/client-price/?id=" + clientID,
success: function(data) {
$( "#amount" ).val(data.price);
});
The view/url would take the id. This post shows how you'd want to format your view to send back a json response.
Thanks onyeka! after some research with ajax and json the code looks like this:
view: (remember to import from django.http import JsonResponse)
def amount(request):
if request.method == 'GET':
total_amount = model.amount
response_data ={}
response_data['amount'] = total_amount
return JsonResponse(response_data)
ajax.js:
$(document).ready(function() {
$('#id_client').change(function(){
var query = $(this).val();
console.log(query);
$.ajax({
url : "/amount/",
type : "GET",
dataType: "json",
data : {
client_response : query
},
success: function(json) {
document.getElementById('id_amount').value=json.amount;
},
failure: function(json) {
alert('Got an error dude');
}
});
});
});
url.py
add corresponding line:
url(r'^amount/$', 'main.views.amount', name='amount'),
Ok, so I'm trying to call the function
def user_timetable(request, userid):
user = get_object_or_404(TwobooksUser,id = userid)
timeSlots = TimeSlot.objects.filter(user = request.user)
rawtimeslots = []
for timeSlot in timeSlots:
newSlot = {
'userid': timeSlot.user.id,
'startTime': str(timeSlot.startTime),
'endTime': str(timeSlot.endTime),
}
rawtimeslots.append(newSlot)
return HttpResponse(simplejson.dumps(rawtimeslots))
through the javascript in
{% include 'elements/header.html' %}
<script type='text/javascript'>
$(document).ready(function() {
$.get('/books/personal{{ user.id }}/timetable/', {}, function(data) {
data = JSON.parse(data);
var events = new Array();
for (var i in data) {
events.push({
id: data[i].id,
title: '{{ request.user.name }}',
start: Date.parse(data[i].startTime, "yyyy-MM-dd HH:mm:ss"),
end: Date.parse(data[i].endTime, "yyyy-MM-dd HH:mm:ss"),
allDay: false
});
}
where the above exists in a template that's being rendered (I think correctly).
The url conf that calls the function user_timetable is
url(r'^books/personal/(?P<userid>\d+)/timetable/$',twobooks.ajax.views.user_timetable),
But, user_timetable isn't being called for some reason.
Can anyone help?
EDIT-
Ok the original problem was that the template was not being rendered correctly, as the url in firebug comes to '/books/personalNone/timetable/' , which is incorrect.
I'm rendering the template like this -
def renderTimetableTemplate(request):
#if request.POST['action'] == "personalTimetable":
user = request.user
return render_to_response(
'books/personal.html',
{
'user': user,
},
context_instance = RequestContext(request)
)
Is there a mistake with this?
There is a slash missing after "personal"
$.get('/books/personal{{ user.id }}/timetable/', {}, function(data) {
should be
$.get('/books/personal/{{ user.id }}/timetable/', {}, function(data) {
Btw. you should use the {% url %} template tag.
There is a mismatch between the data you're converting to JSON and passing to the script, and the data that the script is expecting. You are passing a userId element in each timeslot, whereas the script is expecting just id.
This error should have shown up in your browser's Javascript console, and would be even easier to see in Firebug (or Chrome's built-in Developer Tools).