2015-06-06 81 views
0

我在學習如下Django 1.7教程https://docs.djangoproject.com/en/1.7/intro/tutorial04/。 我從網上覆制代碼,然後運行它。我遇到兩個問題:上下文值似乎沒有傳遞到Django中的ListView?

  1. 在添加繼承ListView的IndexView後,127.0.0.1:8000/polls頁面剛剛返回「沒有民意調查可用」。沒有任何數據庫項目。我對基於分類的觀點感到困惑,似乎上下文值並沒有傳遞給模板。 ---------->解決,這是我愚蠢的類型錯誤。
  2. get_queryset(),什麼是,當這個方法被調用,這是如何映射到上下文?這個函數如何知道上下文映射,如果有兩個上下文和兩個值呢?

有人可以給我一些指導嗎?非常感謝。

民調/ urls.py

from django.conf.urls import patterns, url 

    from . import views 

    urlpatterns = patterns('', 
     url(r'^$', views.IndexView.as_view(), name='index'), 
     #url(r'^$', views.index, name='index'), #this url works 
     url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'), 
     url(r'^(?P<pk>\d+)/results/$', views.ResultsView.as_view(), name='results'), 
     url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'), 
    ) 

民調/ views.py

from django.http import HttpResponse, Http404,HttpResponseRedirect 
    from django.template import RequestContext, loader 
    from django.shortcuts import render,get_object_or_404 
    from .models import Question, Choice 
    from django.core.urlresolvers import reverse 

    from django.views import generic 


    class IndexView(generic.ListView): 
     template_name ='polls/index.html' 
     context_object_name = 'last_question_list' 

     def get_queryset(self): 
      return Question.objects.order_by('-pub_date')[:5] 
    #this works 
    #def index(request):  
    # latest_question_list = Question.objects.order_by('-pub_date')[:5] 
    # context = {'latest_question_list': latest_question_list} 
    # return render(request, 'polls/index.html', context) 

民調/ index.html的

 {% if latest_question_list %} <!-- seems here value is not passed by --> 
      <ul> 
      {% for question in latest_question_list %} 
       <li> 
        {{ question.question_text }}</li> 
      {% endfor %} 
      </ul> 
     {% else %} 
      <p>{{ latest_question_list }}</p> 
      <p>No polls are available.</p> <!-- always display this --> 
      <p>{{ latest_question_list }}</p> 
     {% endif %} 

數據庫

>>> from polls.models import Question 
>>> Question.objects.all() 
[<Question: What's up?>, <Question: tttt>] 
+0

請注意,'context_object_name'是*'last_question_list'*,但在模板中,您正在檢查*'la ** te ** st_question_list'* – soon

+0

是的,已解決。真是愚蠢的錯誤。但仍然如何將last_question_list映射到上下文?我想通過get_queryset(),但問題如何。自動鏈接到last_question_list的objects.order_by(' - pub_date')[:5]。 – Bing

回答

2

由於Django是開源的,因此可以通過context_object_name變量確定queryset如何在模板中變得可用。讓我們來看看django.views.generic.list.py

class MultipleObjectMixin(ContextMixin): 
    # Some fields 
    context_object_name = None 

    def get_queryset(self): 
     # get_queryset implementation 

    def get_context_object_name(self, object_list): 
     """ 
     Get the name of the item to be used in the context. 
     """ 
     if self.context_object_name: 
      return self.context_object_name 
     elif hasattr(object_list, 'model'): 
      return '%s_list' % object_list.model._meta.model_name 
     else: 
      return None 

    def get_context_data(self, **kwargs): 
     queryset = kwargs.pop('object_list', self.object_list) 
     # Some stuff 
     context_object_name = self.get_context_object_name(queryset) 
     # Some other stuff 
     if context_object_name is not None: 
      context[context_object_name] = queryset 
     context.update(kwargs) 
     return super(MultipleObjectMixin, self).get_context_data(**context) 

    # And, of course, a lot of other functions 


class BaseListView(MultipleObjectMixin, View): 
    def get(self, request, *args, **kwargs): 
     self.object_list = self.get_queryset() 
     # Some magic 
     context = self.get_context_data() 
     return self.render_to_response(context) 

    # Skipped 

當你調用get方法,Django的初始化self.object_listget_queryset()。然後,它調用get_context_data()並將上下文數據傳遞給模板。

MultipleObjectMixin.get_context_data返回一個包含name->variable對的字典。它會創建一對get_context_object_name() - >object_list,這就是您可以使用定義的context_object_name名稱訪問您的列表的原因。

0

基於類的視圖通過提供大量預先烘焙的代碼使開發人員的任務變得更容易。 ListView用於返回對象列表。像所有其他視圖的ListView是從View延伸。 View實現了一個get_context_data方法,它傳遞要在模板中使用的數據。所以,現在如果檢查的ListView的get_context_data方法,我們發現這樣的:

def get_context_data(self, **kwargs): 
    """ 
    Get the context for this view. 
    """ 
    queryset = kwargs.pop('object_list', self.object_list) 
    page_size = self.get_paginate_by(queryset) 
    context_object_name = self.get_context_object_name(queryset) 
    if page_size: 
     paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size) 
     context = { 
       'paginator': paginator, 
       'page_obj': page, 
       'is_paginated': is_paginated, 
       'object_list': queryset 
      } 
    else: 
     context = { 
       'paginator': None, 
       'page_obj': None, 
       'is_paginated': False, 
       'object_list': queryset 
      } 
    if context_object_name is not None: 
     context[context_object_name] = queryset 
     context.update(kwargs) 
     return super(MultipleObjectMixin, self).get_context_data(**context) 

正如你所看到的,object_list中設置爲查詢集,或者如果你提供context_object_name,它被設置爲查詢集。並且queryset由您定義的get_queryset設置。

我希望這可以使過程清晰。

相關問題