In my Django web app, I'm trying to dynamically update only a certain section of my page via AJAX, but doing so by returning/replacing HTML in a child template ({% include 'keywords.html' %}). I understand that I can (and maybe should) return a JsonResponse (and I have done so successfully), but I'd like to try and get the below implementation working (as others seem to have).
The view successfully returns the HTML to the AJAX response, but lacking the data contained in the keywords context variable.
templates/index.html
...
<div id="keywords">
{% include 'keywords.html' %}
</div>
...
templates/keywords.html
<div id="keywords">
{% if keywords %}
{% for keyword in keywords %}
<p>{{keyword.word}}</p>
{% endfor %}
{% endif %}
</div>
views.py
def add_keyword(request):
if request.method == 'POST':
form = KeywordForm(request.POST)
if form.is_valid():
...
keywords = Keywords.objects.values()...
print(keywords) # this works, contains a queryset with data
context = {
keywords: keywords,
}
# i've also tried return HttpResponse(render_to_string(...))
# with same result
return render(request, 'keywords.html', context))
index.js
// i've also tried jquery .load()
$.ajax({
url: data.url,
type: "POST",
data:
{
keyword: keyword,
csrfmiddlewaretoken: data.csrf_token
},
success: function(data) {
$("#keywords").html(data);
}
});
AJAX Response data:
<div id="keywords">
</div>
What might I be missing, or doing wrong?
In your context you are missing quotes, when returning the page you have one extra parentheses. It works on my system.
You can render your template with context data using the loade and context
it will do first templates using jinja context will render in html then return final html text then you can pass using JsonResponse
try following stuff then let me know
#view.py
from django.template import context,loader
...
def render_view(request):
if request.method == 'GET':
form = KeywordForm(request.POST)
if form.is_valid():
keywords = Keywords.objects.values()
print(keywords) # this works, contains a queryse
context = {
keywords: keywords,
}
template = loader.get_template('keywords.html')
html = template.render(context)
print(html)
return JsonResponse({'html':html},status=200,content_type="application/json")
#in ajax call success method you should render
success: function(data) {
$("#keywords").html(data);
//or
//ordocument.getElementById('keywords').innerHTML=data;
}
if works or not let me know?
Related
Initially i am loading a modelform with an instance in the template end. But i have to change the instance upon some action using ajax and then refresh the form in the template end. Please suggest me is there any way to do that?
Normally, the server view uses a ModelForm to render a HTML snippet representing an instance of a Model (i.e. {{ myform.as_p }} or similar) that is then placed in a larger template representing an entire HTML document and finally sent to the client.
You need to create a second view that will render and return only the HTML snippet representing the form. From your original template you can then create an ajax call to your new view, which will return the forms HTML. You can replace your existing form with this via jQuery.
view:
def my_second_form(request):
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
...
else:
form = MyForm()
return render(request, 'my_second_form.html', {
'form': form,
})
template:
<form action="/url/to/my_second_form/" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
#djanog function.
def get_doctor_Data(request):
get_doctor = Doctor.objects.get(id=request.GET.get('dept_id'))
# Set initial value of django forms input and send as ajax respons
# If you getting any type of error so use form_name.as_p() method.
edit_form = AddDoctorForm(initial={'name':get_doctor.name, 'dep_id':get_doctor.id})
return HttpResponse(edit_form)
// Ajax method call.
$.ajax({
url: '/department/get_department_Data/',
type: 'GET',
data : {'dept_id': $(this).attr('id')},
success:(data)=>{
if(data){
// open modal
$('#basicModal').modal('show');
// Django forms get using ajax
$('#editForm').html(data)
}
}
})
I'm trying to implement an ajax function that will execute a database query based on the id value of a drop down selection.
The HTML of the drop down list is
<form method = "POST" action="" >{% csrf_token %}
<select name = "parentorgs" id = "parentorgs">
{% for org in parentorg_list %}
<option value = "{{org.parentorg}}" id = "{{org.parentorg}}" >{{ org.parentorgname }}</option>
{% endfor %}
</select>
</form>
A jQuery change() function is used to get the ID of the selection and passes it to
function getData(id) {
$.ajax({
type : "POST",
url : "getData/",
data : {"parentorg" : id},
datatype: "json",
success : function(data) {
console.log(data)
}
});
}
which in turn calls the view function
from django.shortcuts import render_to_response, render
from django.core.context_processors import csrf
def getData(request):
c = {}
c.update(csrf(request))
return render_to_response("app/index.html", c)
Firebug shows that the request is going through via POST, and the method URL is valid. In addition, the URL of this method has been added to urls.py.
At this time, its not doing anything, as I just want to see the response from the method. This method is intended to execute a model query and return the results.
Each time an item is selected in the dropdown, I get an error 403 describing that the view uses ResponseContext rather than Context for the template.
What needs to be done to resolve this issue?
According to the doc
If you’re using Django’s render_to_response() shortcut to populate a template with the contents of a dictionary, your template will be passed a Context instance by default (not a RequestContext). To use a RequestContext in your template rendering, pass an optional third argument to render_to_response(): a RequestContext instance. Your code might look like this:
from django.template import RequestContext
def getData(request):
c = {}
c.update(csrf(request))
return render_to_response("app/index.html", c, context_instance=RequestContext(request))
in views:
return render_to_response("main.html", RequestContext(request, {'form':form, "result":result}))
in template i have this jquery function:
$('#submitButton').click(function(e) {
e.preventDefault();
var dataPosted = $("#mainSubmit").serialize();
$.ajax({
type: "POST",
data: dataPosted,
url: 'main/',
success: function(data) {
$("#mainDiv").html(data);
$(".response").html({{ result }});
$(".response").show();
}
});
});
});
<div id="mainDiv" class="part">
<form id="mainSubmit" action="main/" method="POST" name="submitForm">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.as_p }}
<input type="submit" value="Submit" id="submitButton"/>
<div class="response" style="display: none;"></div>
</form>
</div>
but it seems that data can't be assigned to response div like this(it seems data is not defined). So i don't know what is the way to send data to template. if i use Httpresponse(result) in views, then i can't have my form refreshed, and only i can display in response div data i send from view. so what is the way?
EDIT:
This is my views. before, i didn't put else for the condition if form.is_valid(): , but here i use, because i think if i don't do this, it might cause some probables. i don't know what is the best way.
def mainFunc(request):
if request.is_ajax():
if request.method == 'POST':
form = mainForm(request.POST)
if form.is_valid():
// process the form
result = "successful"
to_json = {'form':form, 'result':result}
return HttpResponse(json.dumps(to_json), mimetype='application/json')
else:
result = ""
to_json = {'form':form, 'result':result}
return HttpResponse(json.dumps(to_json), mimetype='application/json')
else:
form = mainForm()
return render_to_response('main.html', RequestContext(request, {'form':form}))
else:
return render_to_response("ajax.html", {}, context_instance=RequestContext(request))
You need to return a response in format like JSON
You can use this snippet or more simple code like this:
from django.utils import simplejson
to_json = {'form':form, "result":result}
return HttpResponse(simplejson.dumps(to_json), mimetype='application/json')
Then you will be able to use data.result and data.form in your JS code.
If you use the same view for ajax and non-ajax call you can check for it with request.is_ajax()
Also you will not be able to use template tags and filters in your JS callback. So you need to pre-render your form before sending it via JSON
So the final code:
to_json = {'form':form, "result":result}
if request.is_ajax():
to_json['form'] = to_json['form'].as_p()
return HttpResponse(simplejson.dumps(to_json), mimetype='application/json')
else:
render_to_response("main.html", RequestContext(request, {'form':form, "result":result}))
Edit I assume that ajax.html is the template for the whole page and main.html is the template for mainDiv part of the page
So in is_ajax() part of you view you can return the data like this.
to_json = {}
to_json['form'] = render_to_string('main.html', {'form': form}, context_instance=RequestContext(request))
to_json['result'] = result
return HttpResponse(json.dumps(to_json), mimetype='application/json')
And you always return data like this, both for GET and POST AJAX calls
And in JS you get data like this:
$("#mainDiv").html(data.form);
$(".response").html(data.result);
$(".response").show();
PLease i need your help, i'm trying to use jeditable to edit a field on a table inside {% for in %}.
editable DIV:
<td><div class="edit" id="{{ c.id }}">{{ c.name|safe }}</div></td>
jeditable code:
<script>
$(document).ready(function(){
$('.edit').editable('/categoryedit/{{ c.id }}/', {
style: 'display: inline'
});
});
</script>
Url:
url(r'^categoryedit/(?P<id>\d+)/$', 'pos.views.CategoryEdit'),
View:
def CategoryEdit(request, category_id):
id = request.POST.get('category_id', '')
value = request.POST.get('value', '')
categoria = Category.objects.get(pk=id)
categoria.name = value
categoria.save()
return HttpResponse(escape(value))
Solution : The problem was that the editable DIV was inside a {% for %} bucle and in that case is needed to use .each en the Javascript like this...
$('.edit').each(function(){
$('.edit').editable('/categoryedit', {
});
});
and is not necessary to pass the parameters in the url ("/category/1") instead is better to get the parameters using ...
c_id = request.POST.get('id')
the View must be like this:
def CategoryEdit(request):
if request.is_ajax():
if request.method == 'POST':
txt = request.POST.get('value')
c_id = request.POST.get('id')
categoria = Category.objects.get(pk=c_id)
categoria.name = txt
categoria.save()
return HttpResponse(txt)
You probably need to add CSRF data to your javascript. I just ran into this and posted it here:
Django and JEditable: CSRF error
One way to see for sure is to use firebug and look at the ajax response coming back from Django. (If the CSRF info is missing, the Jeditable AJAX call throws a 403 Forbidden error.)
I am doing ajax using jquery in django1.3,well its works fine. Am using jquery load method to fill a in a template.
I get a json object asychrosily when user cliks in a button.I pass it to another template(which i loading inside the div of first template ) as a dictionary. But am unaware of how I display it in template.(I tried to pasres json in template page),but its leads to error.
Can any one suggest How can solve the problem?
So I used normal way parse json in view and pass it to template by using the method locals() in render_to_response(). Is it a good approch?
testjqyery.html
$(document).ready(function() {
$('#save').click(function(e)
{
e.preventDefault();
$( '#results' ).html( ' ' ).load( '{% url t %}' );
});
<div id="results"></div>
views.py
def testupdater(request):
// getting json from server
//contents_json = json.loads(...)
json_data = {'json_dict': contents_json}
return render_to_response( 'results.html' ,json_data,context_instance=RequestContext(request))
results.html
{% if json_dict|length %}
{% else %}
{% endif %}
try it this way
from django.utils import simplejson
data = []
data.append({"msg": 'Hi this message'})
json = simplejson.dumps(data)
return HttpResponse(json, mimetype='application/json')