I am quite late, but I want to document how to combine and adapt the solutions presented by d0ugal
in a way, that it will resolve a much cleaner template-code.
I have a model representing contact persons.
The (generic) view to get one ContactPerson looks like this:
def contcactperson_detail_view(request, name):
try:
person = ContactPerson.objects.get(slug=name)
except:
raise Http404
if request.is_ajax():
return contcactperson_detail_view_ajax(request, person)
return list_detail.object_detail(
request,
queryset = ContactPerson.objects.all(),
object_id = person.id,
template_object_name = "contactperson",
)
@render_to('cms/contactperson_detail_ajax.html')
def contcactperson_detail_view_ajax(request, person):
return {'contactperson':person, 'is_ajax':True}
The template to render the view that handles one ContactPerson is called contcactperson_detail_view.html
:
{% extends "index.html" %}
{% block textpane %}
<h1 id="mainheader">{{ contactperson.first_name }} {{ contactperson.family_name }} </h1>
<div class="indentation"> </div>
{% include 'cms/contactperson_detail_photo.html' %}
<div id="text_pane">
{% include 'cms/contactperson_detail_textpane.html' %}
</div>
{% endblock %}
It includes two sub-templates
contactperson_detail_textpane.html
<p>{{ contactperson.description }}</p>
<ul>
<li>
<dl>
<dt>Email</dt>
<dd>
{{ contactperson.mail }}
</dd>
</dl>
</li>
<li>
<dl>
<dt>Contact Person for</dt>
<dd>
<ul>
{% for c in contactperson.categories.all %}
<li><a href="{% url category-view c.slug %}">{{ c }}</a></li>
{% endfor %}
</ul>
</dd>
</dl>
</li>
</ul>
and contactperson_detail_photo.html
{% with contactperson.photo.detailphoto as pic %}
{% with pic.url as pic_url %}
<div {% if not is_ajax %}id='imageContainer'{% endif %} style="float: right;padding-right:0.5em;
padding-bottom: 1em; padding-left:0.5em;clear:both;
width:{{ pic.width }}px">
<div style="width:{{ pic.width}}px">
<img style="clear:both" src="{{ pic_url }}" alt="{{ i.name }}"/>
</div>
</div>
{% endwith %}
{% endwith %}
this 3 templates will be used, if the request isn't ajax.
But if the request is ajax, contcactperson_detail_view
will return the view contcactperson_detail_view_ajax
, that uses the template contactperson_detail_ajax.html
for rendering. And this template looks like this:
<h1>{{ contactperson.first_name }} {{ contactperson.family_name }}</h1>
{% include 'cms/contactperson_detail_photo.html' %}
{% include 'cms/contactperson_detail_textpane.html' %}
So it uses the same sub-templates but isn't extending anything, therefore only the needed markup delivered. As the ajax view passes is_ajax = True
to the template, it can be used to adjust minor things, like setting correct id-attributes.
No context-processor or additional url-conf needed.
Finally the Javascript code:
$("#contact_person_portlet a").click(function(event){
event.preventDefault();
$.ajax({
type: "GET",
url: event.target.getAttribute('href'),
success: function(msg){
overlay(msg);
}
});
});
Hope that it will be useful for some people. If so, please leave a comment!