Reputation: 25
I don't know why I got a Key Error message (KeyError at / 'post') when I def get_context_data
in PostListView
. But that was totally fine when I just def get_context_data
in PostListDetailView
.
Views.py
def home(request):
post = get_object_or_404(Post, id=request.POST.get('post_id'))
if post.likes.filter(id=request.user.id).exists():
is_liked = True
context = {
'posts': Post.objects.all(),
'is_liked': is_liked,
'total_likes': post.total_likes(),
}
return render(request, 'blog/home.html', context)
def like_post(request): # post like
post = get_object_or_404(Post, id=request.POST.get('post_id'))
is_liked = False
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
is_liked = False
else:
post.likes.add(request.user)
is_liked = True
return HttpResponseRedirect('http://127.0.0.1:8000/')
class PostListView(ListView):
model = Post
template_name = 'blog/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 5
is_liked = False
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
post = context['post']
if post.likes.filter(id=self.request.user.id).exists():
context['is_liked'] = True
return context
class UserPostListView(ListView):
model = Post
template_name = 'blog/user_posts.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
paginate_by = 5
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-date_posted')
class PostDetailView(DetailView):
model = Post
is_liked = False
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
post = context['post']
if post.likes.filter(id=self.request.user.id).exists():
context['is_liked'] = True
return context
Below is the full traceback:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 3.0.4
Python Version: 3.8.2
Installed Applications:
['blog.apps.BlogConfig',
'users.apps.UsersConfig',
'crispy_forms',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "/Users/louisglenn/PycharmProjects/Pblog/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/Users/louisglenn/PycharmProjects/Pblog/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/louisglenn/PycharmProjects/Pblog/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/louisglenn/PycharmProjects/Pblog/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/louisglenn/PycharmProjects/Pblog/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "/Users/louisglenn/PycharmProjects/Pblog/venv/lib/python3.8/site-packages/django/views/generic/list.py", line 157, in get
context = self.get_context_data()
File "/Users/louisglenn/PycharmProjects/Pblog/blog/views.py", line 50, in get_context_data
post = context['post']
Exception Type: KeyError at /
Exception Value: 'post'
But when I changed my key to 'object_list', There is a new error 'AttributeError at / 'QuerySet' object has no attribute 'likes'
__class__
<class 'blog.views.PostListView'>
context
{'is_paginated': True,
'object_list': <QuerySet [<Post: aasd>, <Post: asd>, <Post: ads>, <Post: asd>, <Post: asd>]>,
'page_obj': <Page 1 of 3>,
'paginator': <django.core.paginator.Paginator object at 0x102f6f640>,
'posts': <QuerySet [<Post: aasd>, <Post: asd>, <Post: ads>, <Post: asd>, <Post: asd>]>,
'view': <blog.views.PostListView object at 0x102f6f940>}
kwargs
{}
post
<QuerySet [<Post: aasd>, <Post: asd>, <Post: ads>, <Post: asd>, <Post: asd>]>
self
<blog.views.PostListView object at 0x102f6f940>
Upvotes: 1
Views: 832
Reputation: 5615
Looks like your context data doesn't have the key post
, so this doesn't work
post = context['post']
Keep in mind that DetailView
's get_context_data
(the one being used in PostDetailView
) might not be the exact same as ListView
's get_context_data
(the one being used in PostListView
)
This line in PostDetailView
and PostListView
do not do the same thing-
context = super().get_context_data(**kwargs)
Since super
refers to different classes for these 2. In case of PostDetailView
, it's DetailView
and in case of PostListView
, it's ListView
- hence context
will not be the same across both functions.
You should check the context
variable in each of those 2 different get_context_data
using debugging, and find out which key you actually want.
Edit: To elaborate on how to debug, in case you're using VSCode, here's a quick guide on how to get started.
If you're on Pycharm, here's another quick guide on that!
After you start the debugging sense, you'll be able to setup breakpoints (by clicking next to the line numbers) and your code will pause in this breakpoints. You can then simply use the panels on the left (on VSCode) or bottom (on Pycharm) to view each variable value.
Upvotes: 1