2016-08-31 1 views
2

Dans le code suivant, Comment le modèle details.html sait que album lui est passé par views.py bien que nous ayons jamais revenu ou défini de context_object_name dans DetailsView classe views.py. Veuillez expliquer comment se connectent les différentes choses ici.Vues génériques de Django: Comment DetailView fournit-il automatiquement la variable au template ??

details.html

{% extends 'music/base.html' %} 
{% block title %}AlbumDetails{% endblock %} 

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

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

views.py

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' 

urls.py

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<pk>[0-9]+)/$', views.DetailsView.as_view(), name='details'), 

] 

Merci à l'avance !!

Répondre

3

Si vous vérifiez la mise en œuvre de get_context_name(), vous verrez ceci:

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 

et la mise en œuvre pour get_context_data() (de SingleObjectMixin):

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) 

vous pouvez donc voir que get_context_data() ajoute à le dictionnaire une entrée avec la clé context_object_name (de get_context_object_name()) qui renvoie obj._meta.model_name lorsque self.context_object_name n'est pas définie. Dans ce cas, la vue a obtenu self.object en conséquence de l'appel à get() qui appelle get_object(). get_object() prend le modèle que vous avez défini et l'interroge automatiquement à partir de votre base de données en utilisant le pk que vous avez défini dans votre fichier urls.py.

http://ccbv.co.uk/ est un très bon site Web pour voir toutes les fonctions et les attributs que les vues de classe de Django ont à offrir dans une seule page.

+0

Cela signifie que si j'utilisais un autre nom de variable au lieu de 'album' dans' details.html', cela ne fonctionnerait pas et je dois explicitement définir la variable en utilisant context_object_name, n'est-ce pas? – lordzuko

+0

Pouvez-vous également me dire quand 'get_context_name()' est appelé? – lordzuko

+1

@ lordzuko, à votre premier commentaire, oui :) Le nom de la variable est déterminé par le nom de votre modèle. Vous pouvez le définir explicitement, oui. 'get_context_name()' est appelé dans la méthode 'get()' qui est appelée chaque fois que la vue reçoit une requête GET. –