Почему я получаю ключевую ошибку для 'post' в PostListView - PullRequest
1 голос
/ 19 июня 2020

Я не знаю, почему я получил сообщение об ошибке ключа (KeyError в / 'post'), когда я def get_context_data в PostListView. Но это было совершенно нормально, когда я просто def get_context_data в 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

Ниже приведена полная трассировка:

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'

Но когда я изменил свой ключ на 'object_list', появилась новая ошибка ' AttributeError at / 'QuerySet' объект не имеет атрибута 'нравится'

__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>

1 Ответ

1 голос
/ 19 июня 2020

Похоже, в ваших контекстных данных нет ключа post, поэтому это не работает

post = context['post']

Имейте в виду, что DetailView s get_context_data (тот, который используется в PostDetailView) может не совпадать с ListView get_context_data (тот, который используется в PostListView)

Эта строка в PostDetailView и PostListView не выполняет то же самое -

context = super().get_context_data(**kwargs)

Поскольку super относится к разным классам для этих 2. В случае PostDetailView это DetailView, а в случае PostListView это ListView - следовательно, context не будет одинаковым для обеих функций.

Вы должны проверить переменную context в каждой из этих 2 разных get_context_data с помощью отладки и выяснить, какой ключ вам действительно нужен.

Изменить: чтобы подробнее рассказать о том, как отлаживать, если вы используете VSCode, вот краткое руководство о том, как начать работу.

Если вы используете Pycharm, вот еще одно краткое руководство по этому поводу!

После запуска функции отладки вы сможете настроить точки останова (щелкнув рядом с номерами строк) и d ваш код будет приостановить в этих точках останова. Затем вы можете просто использовать панели слева (в VSCode) или внизу (в Pycharm) для просмотра каждого значения переменной.

...