Джанго - Где переменная контекста? - PullRequest
0 голосов
/ 19 октября 2018

Я все еще привыкаю к ​​представлениям, основанным на классах, в то время как я достигаю общего назначения, некоторые вещи все еще остаются позади меня.Я следую учебному пособию, которое в основном проведет вас через движения, но, как правило, игнорирует нечеткие детали, такие как этот фрагмент кода:

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?Это не контекстная переменная, но кажется, что она используется совершенно неожиданно, почему эта переменная может использоваться?

1 Ответ

0 голосов
/ 19 октября 2018

Представления на основе классов вызывают get_queryset() в методе get() вашего представления. Я приведу пример кода из 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, поэтому, когда вы пытаетесь получить доступ к результирующему QuerySet из get_queryset вк вашему шаблону вы должны получить доступ object_list.

В документации Django об общих представлениях на основе классов есть раздел о расширении ваших контекстных данных с дополнительной информацией.https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-display/#dynamic-filtering

...