Skip to main content
 首页 » 编程设计

python之Django 通用 View :How does DetailView automatically provides the variable to the template

2024年08月22日29itcoder

在下面的代码中,模板 details.html 如何知道 album 是由 views.py 传递给它的,尽管我们有从未在 views.py 的 DetailsView 类中返回或定义任何 context_object_name。 请解释这里的各种事物是如何联系起来的。

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'), 
 
] 

提前致谢!!

请您参考如下方法:

如果检查 get_context_name() 的实现,您会看到:

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 

get_context_data() 的实现(来自 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) 

因此您可以看到 get_context_data() 向字典中添加了一个带有键 context_object_name 的条目(来自 get_context_object_name()),它返回obj._meta.model_name 未定义 self.context_object_name 时。在这种情况下,由于调用 get() 调用 get_object(), View 获得了 self.object。 get_object() 获取您定义的模型,并使用您在 urls.py 中定义的 pk 从数据库中自动查询它> 文件。

http://ccbv.co.uk/是一个非常好的网站,可以在单个页面中查看 Django 基于类的 View 必须提供的所有功能和属性。