【问题标题】:Django - Where is the context variable?Django - 上下文变量在哪里?
【发布时间】:2019-03-23 20:11:15
【问题描述】:

我仍然习惯于基于类的视图,虽然我了解了一般用途,但有些事情仍然无法理解。我正在关注一个教程,该教程基本上会引导您完成动作,但往往会忽略模糊的细节,例如这段代码:

class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView):
    """Generic class-based view listing books on loan to current user."""
    model = BookInstance
    template_name ='books/bookinstance_list_borrowed_user.html'
    paginate_by = 1

    def get_queryset(self):
        return BookInstance.objects.filter(
            borrower=self.request.user
        ).filter(status__exact='o').order_by('due_back')

我得到了model、template_name 和paginate_by 部分,它们是ListView 类的属性,但是我没有得到get_queryset 部分,它在哪里执行?如下面的代码所示,它被称为无处。它返回到哪里?我想我的第一个问题可以归结为“基于类的视图中的函数有什么作用?”

{% extends "base_generic.html" %}

{% block content %}
<h1>Borrowed books</h1>

{% if bookinstance_list %}
<ul>

  {% for bookinst in bookinstance_list %} 
  <li class="{% if bookinst.is_overdue %}text-danger{% endif %}">
    <a href="{% url 'book-detail' bookinst.book.pk %}">{{bookinst.book.title}}</a> ({{ bookinst.due_back }})        
  </li>
  {% endfor %}
</ul>

{% else %}
  <p>There are no books borrowed.</p>
{% endif %}       

那么,有两个问题,第一,get_queryset 返回到哪里,第二,什么是 bookinstance_list?它不是上下文变量,但似乎是突然使用的,为什么这个变量可以使用?

【问题讨论】:

    标签: python django python-3.x django-views


    【解决方案1】:

    基于类的视图在视图的get() 方法中调用get_queryset(),我将展示一些来自Django 1.11 的示例代码。

    # django/views/generic/list.py:159
    def get(self, request, *args, **kwargs):
        self.object_list = self.get_queryset()
        allow_empty = self.get_allow_empty()
    
        ...
    
        context = self.get_context_data()
        return self.render_to_response(context)
    

    ListView 类在此方法中设置self.object_list = self.get_queryset(),但这并没有解释它在传递给模板的上下文中设置它的位置。如果我们快速浏览一下get_context_data()

    # django/views/generic/list.py:127
    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)
    

    context 被分配了一个带有'object_list': queryset 的字典,因此当您尝试从模板中的get_queryset 访问生成的QuerySet 时,您应该访问object_list

    关于基于类的通用视图的 Django 文档有一节介绍如何使用附加信息扩展上下文数据。 https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-display/#dynamic-filtering

    【讨论】:

    猜你喜欢
    • 2011-05-29
    • 2020-12-06
    • 2017-11-25
    • 2014-08-15
    • 2019-07-28
    • 1970-01-01
    • 2013-03-05
    • 2012-06-02
    • 1970-01-01
    相关资源
    最近更新 更多