Django Generic Views :How does DetailView automatically provides the variable to the template ??
<p>In the following code, How does the template <code>details.html</code> knows that <code>album</code> is passed to it by <code>views.py</code> although we have never returned or defined any <code>context_object_name</code> in <code>DetailsView</code> class in <code>views.py</code>. 
Please explain how are the various things getting connected here. </p>

<p><code>details.html</code></p>

<pre><code>{% extends 'music/base.html' %}
{% block title %}AlbumDetails{% endblock %}

{% block body %}
    &lt;img src="{{ album.album_logo }}" style="width: 250px;"&gt;
    &lt;h1&gt;{{ album.album_title }}&lt;/h1&gt;
    &lt;h3&gt;{{ album.artist }}&lt;/h3&gt;

    {% for song in album.song_set.all %}
        {{ song.song_title }}
        {% if song.is_favourite %}
            &lt;img src="http://i.imgur.com/b9b13Rd.png" /&gt;
        {% endif %}
        &lt;br&gt;
    {% endfor %}
{% endblock %}
</code></pre>

<p><code>views.py</code></p>

<pre><code>from django.views import generic
from .models import Album

class IndexView(generic.ListView):
    template_name = 'music/index.html'
    context_object_name = 'album_list'

    def get_queryset(self):
        return Album.objects.all()

class DetailsView(generic.DetailView):
    model = Album
    template_name = 'music/details.html'
</code></pre>

<p><code>urls.py</code></p>

<pre><code>from django.conf.urls import url
from . import views

app_name = 'music'

urlpatterns = [

    # /music/
    url(r'^$', views.IndexView.as_view(), name='index'),

    # /music/album_id/
    url(r'^(?P&lt;pk&gt;[0-9]+)/$', views.DetailsView.as_view(), name='details'),

]
</code></pre>

<p>Thanks in advance !!</p>

<p>If you check the implementation of <code>get_context_name()</code>, you'll see this:</p>

<pre><code>def get_context_object_name(self, obj):
    """
    Get the name to use for the object.
    """
    if self.context_object_name:
        return self.context_object_name
    elif isinstance(obj, models.Model):
        return obj._meta.model_name
    else:
        return None
</code></pre>

<p>And the implementation for <code>get_context_data()</code> (from <code>SingleObjectMixin</code>):</p>

<pre><code>def get_context_data(self, **kwargs):
    """
    Insert the single object into the context dict.
    """
    context = {}
    if self.object:
        context['object'] = self.object
        context_object_name = self.get_context_object_name(self.object)
        if context_object_name:
            context[context_object_name] = self.object
    context.update(kwargs)
    return super(SingleObjectMixin, self).get_context_data(**context)
</code></pre>

<p>So you can see that <code>get_context_data()</code> adds to the dictionary an entry with the key <code>context_object_name</code> (from <code>get_context_object_name()</code>) which returns <code>obj._meta.model_name</code> when <code>self.context_object_name</code> isn't defined. In this case, the view got <code>self.object</code> as a consequence of the call to <code>get()</code> which calls <code>get_object()</code>. <code>get_object()</code> takes the model that you've defined and automatically queries it from your database using the <code>pk</code> you've defined in your <code>urls.py</code> file.</p>

<p><a href="http://ccbv.co.uk/" rel="nofollow">http://ccbv.co.uk/</a> is a very good website for seeing all of the functions and attributes the class based views of Django has to offer in a single page.</p>

python django django-generic-views