Django переопределение get_context_data() не отображается в шаблоне

Я учусь работать с CBV и в настоящее время работаю над простым списком дел, я хочу получить данные конкретных пользователей для конкретных пользователей. Я делаю это путем переопределения метода get_context_data() в моем классе ListView, но данные не отображаются в моем шаблоне. Я создал несколько пользователей и создал несколько задач, но все равно не работает, хотя я могу получить к ним доступ через страницу администратора.

Вот мой код:

views.py:

class TaskList(LoginRequiredMixin, ListView):
    model = Task
    template_name = 'app/home.html'
    context_object_name = 'tasks'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['tasks'] = context['tasks'].filter(user=self.request.user)
        context['count'] = context['tasks'].filter(
            complete=False).count()
        return context

urls.py:

from django.urls import path

from .views import (
    TaskList,
    TaskDetail,
    TaskCreate,
    TaskUpdate,
    TaskDelete,

    UserLogin,
    UserLogout
)

urlpatterns = [
    path('login/', UserLogin.as_view(), name='login'),
    path('logout/', UserLogout.as_view(), name='logout'),


    path('', TaskList.as_view(), name='home'),
    path('task-detail/<int:pk>/', TaskDetail.as_view(), name='task-detail'),
    path('task-create/', TaskCreate.as_view(), name='task-create'),
    path('task-update/<int:pk>/', TaskUpdate.as_view(), name='task-update'),
    path('task-delete/<int:pk>/', TaskDelete.as_view(), name='task-delete')
]

home.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>To Do List</title>
</head>
<body>
    {% if request.user.is_authenticated %}
        <p>{{ request.user }}</p>
        <a href="{% url 'logout' %}">Logout</a>
    {% else %}
        <a href="{% url 'login' %}">Login</a>
    {% endif %}    
    <hr>
    <a href="{% url 'task-create' %}">Add Task</a>
    <table>
        <tr>
            <th>
                Items
            </th>
        </tr>
        {% for task in tasks %}
        <tr>
            <td>
                {{ task }}
            </td>
            <td>
                <a href="{% url 'task-detail' task.id %}">View</a>
            </td>
            <td>
                <a href="{% url 'task-update' task.id %}">Edit</a>
            </td>
            <td>
                <a href="{% url 'task-delete' task.id %}">Delete</a>
            </td>
        </tr>
        {% endfor %}

    </table>
</body>
</html>

Я заметил, что когда я закомментирую строку: context['tasks'] = context['tasks'].filter(user=self.request.user) данные действительно отображаются в моем шаблоне, но не для конкретного пользователя. Что это значит? Кроме того, добавление другого контекста, похоже, работает, но не тогда, когда я пытаюсь получить данные для конкретного пользователя. Мне кажется, что я упускаю что-то маленькое, но я не могу понять это.

filter() метод или любой метод querysets должен применяться к моделям, а не к пустым ключам словаря (например:tasks).

Попробуйте это:

Views.py

class TaskList(LoginRequiredMixin, ListView):
    model = Task
    template_name = 'app/home.html'
    context_object_name = 'all_tasks'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['tasks'] = self.model.objects.filter(user=self.request.user)
        context['count'] = self.model.objects.filter(
            complete=False).count()
        return context

all_tasks даст все объекты модели Task, поскольку именно ListView дает все экземпляры, тогда как tasks, находящийся в контексте get_context_data, даст конкретные задачи пользователя.

Тогда вы можете запустить цикл в шаблоне.

Note: При работе с представлениями, основанными на классах, лучше использовать в качестве суффикса фактическое имя представления, поэтому будет лучше, если вы назовете его как TaskListView, а не только TaskView.

Вернуться на верх