Django 覆盖 get_context_data() 不在模板中呈现
Django overriding get_context_data() not rendering in template
我正在学习使用 CBV,我目前正在处理一个简单的待办事项列表,我想获取特定用户的特定用户数据。我这样做的方法是覆盖 ListView
class 中的 get_context_data()
方法,但数据未显示在我的模板中。我创建了多个用户并创建了多个任务,但即使我可以通过管理页面访问它们,仍然无法使用。
这是我的代码:
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
models.py:
from django.db import models
from django.contrib.auth.models import User
class Task(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, blank=True, null=True)
title = models.CharField(max_length=150)
description = models.TextField(max_length=500)
complete = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
# Order by completion
class Meta:
ordering = ['complete']
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()
方法或查询集的任何方法必须应用于模型而不是空字典键(例如:任务)。
试试这个:
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 的上下文中会给用户特定的任务。
然后,您可以运行在模板中循环。
另一种最佳方法:
如果您只想在模板 app/home.html
中使用特定于用户的数据,那么您可以通过以下方式简单地覆盖 TaskView
中的 get_queryset
:
views.py
class TaskList(LoginRequiredMixin, ListView):
model = Task
template_name = 'app/home.html'
context_object_name = 'tasks'
def get_queryset(self):
qs = super().get_queryset()
return qs.filter(user=self.request.user)
#for count you have specifiy in get_context_data
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['count'] = self.model.objects.filter(complete=False).count()
return context
然后,无需更改模板文件中的代码,您将能够访问用户特定数据。
Note:
It is better to use actual view name as the suffix while working with class based views, so it will be better if you name it as TaskListView
instead of only TaskView
.
我正在学习使用 CBV,我目前正在处理一个简单的待办事项列表,我想获取特定用户的特定用户数据。我这样做的方法是覆盖 ListView
class 中的 get_context_data()
方法,但数据未显示在我的模板中。我创建了多个用户并创建了多个任务,但即使我可以通过管理页面访问它们,仍然无法使用。
这是我的代码:
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
models.py:
from django.db import models
from django.contrib.auth.models import User
class Task(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, blank=True, null=True)
title = models.CharField(max_length=150)
description = models.TextField(max_length=500)
complete = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
# Order by completion
class Meta:
ordering = ['complete']
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()
方法或查询集的任何方法必须应用于模型而不是空字典键(例如:任务)。
试试这个:
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 的上下文中会给用户特定的任务。
然后,您可以运行在模板中循环。
另一种最佳方法:
如果您只想在模板 app/home.html
中使用特定于用户的数据,那么您可以通过以下方式简单地覆盖 TaskView
中的 get_queryset
:
views.py
class TaskList(LoginRequiredMixin, ListView):
model = Task
template_name = 'app/home.html'
context_object_name = 'tasks'
def get_queryset(self):
qs = super().get_queryset()
return qs.filter(user=self.request.user)
#for count you have specifiy in get_context_data
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['count'] = self.model.objects.filter(complete=False).count()
return context
然后,无需更改模板文件中的代码,您将能够访问用户特定数据。
Note:
It is better to use actual view name as the suffix while working with class based views, so it will be better if you name it asTaskListView
instead of only.TaskView