Return Django Models for Template Rendering after an Ajax Request
I would like to create an AJAX-based search for my webpage. So far I am able to send the form data and make the appropriate call to my Django model. What I am having a hard tim开发者_Go百科e with is just sending the Queryset back and having it rendered using the Django templating system. Your help/advice is greatly appreciated.
Here is the code I am working with.
views.py
if request.is_ajax():
if request.method == 'POST':
format = 'json'
mimetype = 'application/json'
try:
q = request.POST['obj']
o = Object.objects.filter(name__icontains=q)
return render_to_response( 'project_view_objects.html', {'username': request.user.username, 'results':o})
view.html
<script>
$(document).ready(function(){
$("#search_form").submit(function(event)
{
event.preventDefault();
$.ajax({
type: "POST",
url: "/objects/search/",
data: $(this).serialize(),
processData: false,
dataType: "json"
});
});});
</script>
<article>
<blockquote>
<form class="create_form" id="search_form">
<p>
<input id="objectSearchNameInput" type="text" name="obj" value="Object name">
<input type="submit" value="search objects">
</p>
</form>
</blockquote>
</article>
<br />
{% if results %}
<blockquote>
<aside class="column">
{% for object in results %}
<b><a href="#" class="extra-text-special">{{ object.name }}</a></b><br />
{% endfor %}
</aside>
<aside class="column">
{% for object in results %}
<font class="extra-text-nospecial">{{ object.created_when }}</font><br />
{% endfor %}
</aside>
</blockquote>
{% else %}
<p>haha</p>
{% endif %}
At the moment, all I see displayed on the page is 'haha'.
The thing you're missing is that the template has already been rendered by the time the AJAX is fired - as of course it must be, because templates are server-side and javascript is client-side.
So the thing to do is to get your Ajax views not to return JSON, but rendered templates, which your Javascript callback then inserts into the template.
this is the final answer
python
if request.is_ajax():
if request.method == 'POST':
format = 'json'
mimetype = 'application/json'
try:
q = request.POST['obj']
#message = {"object_name": "hey, you made it"}
o = Object.objects.filter(name__icontains=q)
except:
message = {"object_name": "didn't make it"}
#m = str(q['id'])
#json = simplejson.dumps(message)
#data = serializers.serialize(format, o)
#return HttpResponse(data, mimetype)
html = render_to_string( 'results.html', { 'username': request.user.username, 'objects': o } )
res = {'html': html}
return HttpResponse( simplejson.dumps(res), mimetype )
html
<script>
$(document).ready(function(){
$("#search_form").submit(function(event)
{
event.preventDefault();
$.ajax({
type: "POST",
url: "/objects/search/",
data: $(this).serialize(),
processData: false,
dataType: "json",
success: function( data ){
$( '#results' ).html( data.html );
}
});
});});
</script>
. . .
<article>
<blockquote>
<form class="create_form" id="search_form">
<p>
<input id="objectSearchNameInput" type="text" name="obj" value="Object name">
<input type="submit" value="search objects">
</p>
</form>
</blockquote>
</article>
<br />
<aside id="results">
</aside>
My solution was using Dajax, creating small fragment templates for for instance rendering a list. Then render them in the Dajax functions, and write them in the document with the appropriate javascript calls. You can see an example on (and actually all the documentation of dajax is quite good): http://www.dajaxproject.com/pagination/
Another solution which I recently found (but have not tried myself) is: http://www.jperla.com/blog/post/write-bug-free-javascript-with-pebbles
Lastly you might go totally the other way and use Backbone.js, but in that way you (more or less) end up with the same problem, how to share backbone templates with django templates (I think you should be able to write a template tag, which dependant on the 'mode' writes either a value, or a backbone template tag, thus allowing you to reuse your templates)
精彩评论