KeyError at / how to fix this error?

Environment:

Request Method: GET
Request URL: http://127.0.0.1:8000/

Django Version: 3.2.9
Python Version: 3.10.0
Installed Applications:
[‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘mainapp’,
‘crispy_forms’]
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 “C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py”, line 47, in inner
response = get_response(request)
File “C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py”, line 181, in _get_response
response = wrapped_callback(request, callback_args, callback_kwargs)
File “C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\base.py”, line 70, in view
return self.dispatch(request, *args, **kwargs)
File “E:\Progerstvo\Django\django3-ecommerce-master\mainapp\mixins.py”, line 43, in dispatch
return super().dispatch(request, *args, **kwargs)
File “C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\base.py”, line 98, in dispatch
return handler(request, *args, **kwargs)
File “E:\Progerstvo\Django\django3-ecommerce-master\mainapp\views.py”, line 17, in get
categories = Category.objects.get_categories_for_left_sidebar()
File “E:\Progerstvo\Django\django3-ecommerce-master\mainapp\models.py”, line 58, in get_categories_for_left_sidebar
data = [
File “E:\Progerstvo\Django\django3-ecommerce-master\mainapp\models.py”, line 59, in
dict(name=c.name, url=c.get_absolute_url(), count=getattr(c, self.CATEGORY_NAME_COUNT_NAME[c.name]))

Exception Type: KeyError at /
Exception Value: ‘Сматфоны’

models.py

from django.db import models
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.urls import reverse
from django.utils import timezone

User = get_user_model()

def get_models_for_count(*model_names):
return [models.Count(model_name) for model_name in model_names]

def get_product_url(obj, viewname):
ct_model = obj.class._meta.model_name
return reverse(viewname, kwargs={‘ct_model’: ct_model, ‘slug’: obj.slug})

class LatestProductsManager:

@staticmethod
def get_products_for_main_page(*args, **kwargs):
    with_respect_to = kwargs.get('with_respect_to')
    products = []
    ct_models = ContentType.objects.filter(model__in=args)
    for ct_model in ct_models:
        model_products = ct_model.model_class()._base_manager.all().order_by('-id')[:5]
        products.extend(model_products)
    if with_respect_to:
        ct_model = ContentType.objects.filter(model=with_respect_to)
        if ct_model.exists():
            if with_respect_to in args:
                return sorted(
                    products, key=lambda x: x.__class__._meta.model_name.startswith(with_respect_to), reverse=True
                )
    return products

class LatestProducts:

objects = LatestProductsManager()

class CategoryManager(models.Manager):

CATEGORY_NAME_COUNT_NAME = {
    'Ноутбуки': 'notebook__count',
    'Смартфоны': 'smartphone__count'
}

def get_queryset(self):
    return super().get_queryset()

def get_categories_for_left_sidebar(self):
    models = get_models_for_count('notebook', 'smartphone')
    qs = list(self.get_queryset().annotate(*models))
    data = [
        dict(name=c.name, url=c.get_absolute_url(), count=getattr(c, self.CATEGORY_NAME_COUNT_NAME[c.name]))
        for c in qs
    ]
    return data

class Category(models.Model):

name = models.CharField(max_length=255, verbose_name='Имя категории')
slug = models.SlugField(unique=True)
objects = CategoryManager()

def __str__(self):
    return self.name

def get_absolute_url(self):
    return reverse('category_detail', kwargs={'slug': self.slug})

class Product(models.Model):

class Meta:
    abstract = True

category = models.ForeignKey(Category, verbose_name='Категория', on_delete=models.CASCADE)
title = models.CharField(max_length=255, verbose_name='Наименование')
slug = models.SlugField(unique=True)
image = models.ImageField(verbose_name='Изображение')
description = models.TextField(verbose_name='Описание', null=True)
price = models.DecimalField(max_digits=9, decimal_places=2, verbose_name='Цена')

def __str__(self):
    return self.title

def get_model_name(self):
    return self.__class__.__name__.lower()

class Notebook(Product):

diagonal = models.CharField(max_length=255, verbose_name='Диагональ')
display_type = models.CharField(max_length=255, verbose_name='Тип дисплея')
processor_freq = models.CharField(max_length=255, verbose_name='Частота процессора')
ram = models.CharField(max_length=255, verbose_name='Оперативная память')
video = models.CharField(max_length=255, verbose_name='Видеокарта')
time_without_charge = models.CharField(max_length=255, verbose_name='Время работы аккумулятора')

def __str__(self):
    return "{} : {}".format(self.category.name, self.title)

def get_absolute_url(self):
    return get_product_url(self, 'product_detail')

class Smartphone(Product):

diagonal = models.CharField(max_length=255, verbose_name='Диагональ')
display_type = models.CharField(max_length=255, verbose_name='Тип дисплея')
resolution = models.CharField(max_length=255, verbose_name='Разрешение экрана')
accum_volume = models.CharField(max_length=255, verbose_name='Объем батареи')
ram = models.CharField(max_length=255, verbose_name='Оперативная память')
sd = models.BooleanField(null=True, verbose_name='Наличие SD карты')
sd_volume_max = models.CharField(
    max_length=255, null=True, blank=True, verbose_name='Максимальный объем встраивамой памяти'
)
main_cam_mp = models.CharField(max_length=255, verbose_name='Главная камера')
frontal_cam_mp = models.CharField(max_length=255, verbose_name='Фронтальная камера')

def __str__(self):
    return "{} : {}".format(self.category.name, self.title)

def get_absolute_url(self):
    return get_product_url(self, 'product_detail')

class CartProduct(models.Model):

user = models.ForeignKey('Customer', verbose_name='Покупатель', on_delete=models.CASCADE)
cart = models.ForeignKey('Cart', verbose_name='Корзина', on_delete=models.CASCADE, related_name='related_products')
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
qty = models.PositiveIntegerField(default=1)
final_price = models.DecimalField(max_digits=9, decimal_places=2, verbose_name='Общая цена')

def __str__(self):
    return "Продукт: {} (для корзины)".format(self.content_object.title)

def save(self, *args, **kwargs):
    self.final_price = self.qty * self.content_object.price
    super().save(*args, **kwargs)

class Cart(models.Model):

owner = models.ForeignKey('Customer', null=True, verbose_name='Владелец', on_delete=models.CASCADE)
products = models.ManyToManyField(CartProduct, blank=True, related_name='related_cart')
total_products = models.PositiveIntegerField(default=0)
final_price = models.DecimalField(max_digits=9, default=0, decimal_places=2, verbose_name='Общая цена')
in_order = models.BooleanField(default=False)
for_anonymous_user = models.BooleanField(default=False)

def __str__(self):
    return str(self.id)

class Customer(models.Model):

user = models.ForeignKey(User, verbose_name='Пользователь', on_delete=models.CASCADE)
phone = models.CharField(max_length=20, verbose_name='Номер телефона', null=True, blank=True)
address = models.CharField(max_length=255, verbose_name='Адрес', null=True, blank=True)
orders = models.ManyToManyField('Order', verbose_name='Заказы покупателя', related_name='related_order')

def __str__(self):
    return "Покупатель: {} {}".format(self.user.first_name, self.user.last_name)

class Order(models.Model):

STATUS_NEW = 'new'
STATUS_IN_PROGRESS = 'in_progress'
STATUS_READY = 'is_ready'
STATUS_COMPLETED = 'completed'

BUYING_TYPE_SELF = 'self'
BUYING_TYPE_DELIVERY = 'delivery'

STATUS_CHOICES = (
    (STATUS_NEW, 'Новый заказ'),
    (STATUS_IN_PROGRESS, 'Заказ в обработке'),
    (STATUS_READY, 'Заказ готов'),
    (STATUS_COMPLETED, 'Заказ выполнен')
)

BUYING_TYPE_CHOICES = (
    (BUYING_TYPE_SELF, 'Самовывоз'),
    (BUYING_TYPE_DELIVERY, 'Доставка')
)

customer = models.ForeignKey(Customer, verbose_name='Покупатель', related_name='related_orders', on_delete=models.CASCADE)
first_name = models.CharField(max_length=255, verbose_name='Имя')
last_name = models.CharField(max_length=255, verbose_name='Фамилия')
phone = models.CharField(max_length=20, verbose_name='Телефон')
cart = models.ForeignKey(Cart, verbose_name='Корзина', on_delete=models.CASCADE, null=True, blank=True)
address = models.CharField(max_length=1024, verbose_name='Адрес', null=True, blank=True)
status = models.CharField(
    max_length=100,
    verbose_name='Статус заказ',
    choices=STATUS_CHOICES,
    default=STATUS_NEW
)
buying_type = models.CharField(
    max_length=100,
    verbose_name='Тип заказа',
    choices=BUYING_TYPE_CHOICES,
    default=BUYING_TYPE_SELF
)
comment = models.TextField(verbose_name='Комментарий к заказу', null=True, blank=True)
created_at = models.DateTimeField(auto_now=True, verbose_name='Дата создания заказа')
order_date = models.DateField(verbose_name='Дата получения заказа', default=timezone.now)

def __str__(self):
    return str(self.id)

views.py

from django.db import transaction
from django.shortcuts import render
from django.contrib.contenttypes.models import ContentType
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.views.generic import DetailView, View

from .models import Notebook, Smartphone, Category, LatestProducts, Customer, Cart, CartProduct
from .mixins import CategoryDetailMixin, CartMixin
from .forms import OrderForm
from .utils import recalc_cart

class BaseView(CartMixin, View):

def get(self, request, *args, **kwargs):
    categories = Category.objects.get_categories_for_left_sidebar()
    products = LatestProducts.objects.get_products_for_main_page(
        'notebook', 'smartphone', with_respect_to='notebook'
    )
    context = {
        'categories': categories,
        'products': products,
        'cart': self.cart
    }
    return render(request, 'base.html', context)

class ProductDetailView(CartMixin, CategoryDetailMixin, DetailView):

CT_MODEL_MODEL_CLASS = {
    'notebook': Notebook,
    'smartphone': Smartphone
}

def dispatch(self, request, *args, **kwargs):
    self.model = self.CT_MODEL_MODEL_CLASS[kwargs['ct_model']]
    self.queryset = self.model._base_manager.all()
    return super().dispatch(request, *args, **kwargs)

context_object_name = 'product'
template_name = 'product_detail.html'
slug_url_kwarg = 'slug'

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['ct_model'] = self.model._meta.model_name
    context['cart'] = self.cart
    return context

class CategoryDetailView(CartMixin, CategoryDetailMixin, DetailView):

model = Category
queryset = Category.objects.all()
context_object_name = 'category'
template_name = 'category_detail.html'
slug_url_kwarg = 'slug'

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['cart'] = self.cart
    return context

class AddToCartView(CartMixin, View):

def get(self, request, *args, **kwargs):
    ct_model, product_slug = kwargs.get('ct_model'), kwargs.get('slug')
    content_type = ContentType.objects.get(model=ct_model)
    product = content_type.model_class().objects.get(slug=product_slug)
    cart_product, created = CartProduct.objects.get_or_create(
        user=self.cart.owner, cart=self.cart, content_type=content_type, object_id=product.id
    )
    if created:
        self.cart.products.add(cart_product)
    recalc_cart(self.cart)
    messages.add_message(request, messages.INFO, "Товар успешно добавлен")
    return HttpResponseRedirect('/cart/')

class DeleteFromCartView(CartMixin, View):

def get(self, request, *args, **kwargs):
    ct_model, product_slug = kwargs.get('ct_model'), kwargs.get('slug')
    content_type = ContentType.objects.get(model=ct_model)
    product = content_type.model_class().objects.get(slug=product_slug)
    cart_product = CartProduct.objects.get(
        user=self.cart.owner, cart=self.cart, content_type=content_type, object_id=product.id
    )
    self.cart.products.remove(cart_product)
    cart_product.delete()
    recalc_cart(self.cart)
    messages.add_message(request, messages.INFO, "Товар успешно удален")
    return HttpResponseRedirect('/cart/')

class ChangeQTYView(CartMixin, View):

def post(self, request, *args, **kwargs):
    ct_model, product_slug = kwargs.get('ct_model'), kwargs.get('slug')
    content_type = ContentType.objects.get(model=ct_model)
    product = content_type.model_class().objects.get(slug=product_slug)
    cart_product = CartProduct.objects.get(
        user=self.cart.owner, cart=self.cart, content_type=content_type, object_id=product.id
    )
    qty = int(request.POST.get('qty'))
    cart_product.qty = qty
    cart_product.save()
    recalc_cart(self.cart)
    messages.add_message(request, messages.INFO, "Кол-во успешно изменено")
    return HttpResponseRedirect('/cart/')

class CartView(CartMixin, View):

def get(self, request, *args, **kwargs):
    categories = Category.objects.get_categories_for_left_sidebar()
    context = {
        'cart': self.cart,
        'categories': categories
    }
    return render(request, 'cart.html', context)

class CheckoutView(CartMixin, View):

def get(self, request, *args, **kwargs):
    categories = Category.objects.get_categories_for_left_sidebar()
    form = OrderForm(request.POST or None)
    context = {
        'cart': self.cart,
        'categories': categories,
        'form': form
    }
    return render(request, 'checkout.html', context)

class MakeOrderView(CartMixin, View):

@transaction.atomic
def post(self, request, *args, **kwargs):
    form = OrderForm(request.POST or None)
    customer = Customer.objects.get(user=request.user)
    if form.is_valid():
        new_order = form.save(commit=False)
        new_order.customer = customer
        new_order.first_name = form.cleaned_data['first_name']
        new_order.last_name = form.cleaned_data['last_name']
        new_order.phone = form.cleaned_data['phone']
        new_order.address = form.cleaned_data['address']
        new_order.buying_type = form.cleaned_data['buying_type']
        new_order.order_date = form.cleaned_data['order_date']
        new_order.comment = form.cleaned_data['comment']
        new_order.save()
        self.cart.in_order = True
        self.cart.save()
        new_order.cart = self.cart
        new_order.save()
        customer.orders.add(new_order)
        messages.add_message(request, messages.INFO, 'Спасибо за заказ! Менеджер с Вами свяжется')
        return HttpResponseRedirect('/')
    return HttpResponseRedirect('/checkout/')

mixins.py

from django.views.generic.detail import SingleObjectMixin
from django.views.generic import View

from .models import Category, Cart, Customer, Notebook, Smartphone

class CategoryDetailMixin(SingleObjectMixin):

CATEGORY_SLUG2PRODUCT_MODEL = {
    'notebooks': Notebook,
    'smartphones': Smartphone
}

def get_context_data(self, **kwargs):
    if isinstance(self.get_object(), Category):
        model = self.CATEGORY_SLUG2PRODUCT_MODEL[self.get_object().slug]
        context = super().get_context_data(**kwargs)
        context['categories'] = Category.objects.get_categories_for_left_sidebar()
        context['category_products'] = model.objects.all()
        return context
    context = super().get_context_data(**kwargs)
    context['categories'] = Category.objects.get_categories_for_left_sidebar()
    return context

class CartMixin(View):

def dispatch(self, request, *args, **kwargs):
    if request.user.is_authenticated:
        customer = Customer.objects.filter(user=request.user).first()
        if not customer:
            customer = Customer.objects.create(
                user=request.user
            )
        cart = Cart.objects.filter(owner=customer, in_order=False).first()
        if not cart:
            cart = Cart.objects.create(owner=customer)
    else:
        cart = Cart.objects.filter(for_anonymous_user=True).first()
        if not cart:
            cart = Cart.objects.create(for_anonymous_user=True)
    self.cart = cart
    return super().dispatch(request, *args, **kwargs)

base.py
import logging
from functools import update_wrapper

from django.core.exceptions import ImproperlyConfigured
from django.http import (
HttpResponse, HttpResponseGone, HttpResponseNotAllowed,
HttpResponsePermanentRedirect, HttpResponseRedirect,
)
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils.decorators import classonlymethod

logger = logging.getLogger(‘django.request’)

class ContextMixin:
“”"
A default context mixin that passes the keyword arguments received by
get_context_data() as the template context.
“”"
extra_context = None

def get_context_data(self, **kwargs):
    kwargs.setdefault('view', self)
    if self.extra_context is not None:
        kwargs.update(self.extra_context)
    return kwargs

class View:
“”"
Intentionally simple parent class for all views. Only implements
dispatch-by-method and simple sanity checking.
“”"

http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

def __init__(self, **kwargs):
    """
    Constructor. Called in the URLconf; can contain helpful extra
    keyword arguments, and other things.
    """
    # Go through keyword arguments, and either save their values to our
    # instance, or raise an error.
    for key, value in kwargs.items():
        setattr(self, key, value)

@classonlymethod
def as_view(cls, **initkwargs):
    """Main entry point for a request-response process."""
    for key in initkwargs:
        if key in cls.http_method_names:
            raise TypeError(
                'The method name %s is not accepted as a keyword argument '
                'to %s().' % (key, cls.__name__)
            )
        if not hasattr(cls, key):
            raise TypeError("%s() received an invalid keyword %r. as_view "
                            "only accepts arguments that are already "
                            "attributes of the class." % (cls.__name__, key))

    def view(request, *args, **kwargs):
        self = cls(**initkwargs)
        self.setup(request, *args, **kwargs)
        if not hasattr(self, 'request'):
            raise AttributeError(
                "%s instance has no 'request' attribute. Did you override "
                "setup() and forget to call super()?" % cls.__name__
            )
        return self.dispatch(request, *args, **kwargs)
    view.view_class = cls
    view.view_initkwargs = initkwargs

    # take name and docstring from class
    update_wrapper(view, cls, updated=())

    # and possible attributes set by decorators
    # like csrf_exempt from dispatch
    update_wrapper(view, cls.dispatch, assigned=())
    return view

def setup(self, request, *args, **kwargs):
    """Initialize attributes shared by all view methods."""
    if hasattr(self, 'get') and not hasattr(self, 'head'):
        self.head = self.get
    self.request = request
    self.args = args
    self.kwargs = kwargs

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)

def http_method_not_allowed(self, request, *args, **kwargs):
    logger.warning(
        'Method Not Allowed (%s): %s', request.method, request.path,
        extra={'status_code': 405, 'request': request}
    )
    return HttpResponseNotAllowed(self._allowed_methods())

def options(self, request, *args, **kwargs):
    """Handle responding to requests for the OPTIONS HTTP verb."""
    response = HttpResponse()
    response.headers['Allow'] = ', '.join(self._allowed_methods())
    response.headers['Content-Length'] = '0'
    return response

def _allowed_methods(self):
    return [m.upper() for m in self.http_method_names if hasattr(self, m)]

class TemplateResponseMixin:
“”“A mixin that can be used to render a template.”""
template_name = None
template_engine = None
response_class = TemplateResponse
content_type = None

def render_to_response(self, context, **response_kwargs):
    """
    Return a response, using the `response_class` for this view, with a
    template rendered with the given context.

    Pass response_kwargs to the constructor of the response class.
    """
    response_kwargs.setdefault('content_type', self.content_type)
    return self.response_class(
        request=self.request,
        template=self.get_template_names(),
        context=context,
        using=self.template_engine,
        **response_kwargs
    )

def get_template_names(self):
    """
    Return a list of template names to be used for the request. Must return
    a list. May not be called if render_to_response() is overridden.
    """
    if self.template_name is None:
        raise ImproperlyConfigured(
            "TemplateResponseMixin requires either a definition of "
            "'template_name' or an implementation of 'get_template_names()'")
    else:
        return [self.template_name]

class TemplateView(TemplateResponseMixin, ContextMixin, View):
“”"
Render a template. Pass keyword arguments from the URLconf to the context.
“”"
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context)

class RedirectView(View):
“”“Provide a redirect on any GET request.”""
permanent = False
url = None
pattern_name = None
query_string = False

def get_redirect_url(self, *args, **kwargs):
    """
    Return the URL redirect to. Keyword arguments from the URL pattern
    match generating the redirect request are provided as kwargs to this
    method.
    """
    if self.url:
        url = self.url % kwargs
    elif self.pattern_name:
        url = reverse(self.pattern_name, args=args, kwargs=kwargs)
    else:
        return None

    args = self.request.META.get('QUERY_STRING', '')
    if args and self.query_string:
        url = "%s?%s" % (url, args)
    return url

def get(self, request, *args, **kwargs):
    url = self.get_redirect_url(*args, **kwargs)
    if url:
        if self.permanent:
            return HttpResponsePermanentRedirect(url)
        else:
            return HttpResponseRedirect(url)
    else:
        logger.warning(
            'Gone: %s', request.path,
            extra={'status_code': 410, 'request': request}
        )
        return HttpResponseGone()

def head(self, request, *args, **kwargs):
    return self.get(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
    return self.get(request, *args, **kwargs)

def options(self, request, *args, **kwargs):
    return self.get(request, *args, **kwargs)

def delete(self, request, *args, **kwargs):
    return self.get(request, *args, **kwargs)

def put(self, request, *args, **kwargs):
    return self.get(request, *args, **kwargs)

def patch(self, request, *args, **kwargs):
    return self.get(request, *args, **kwargs)

exception.py
import asyncio
import logging
import sys
from functools import wraps

from asgiref.sync import sync_to_async

from django.conf import settings
from django.core import signals
from django.core.exceptions import (
BadRequest, PermissionDenied, RequestDataTooBig, SuspiciousOperation,
TooManyFieldsSent,
)
from django.http import Http404
from django.http.multipartparser import MultiPartParserError
from django.urls import get_resolver, get_urlconf
from django.utils.log import log_response
from django.views import debug

def convert_exception_to_response(get_response):
“”"
Wrap the given get_response callable in exception-to-response conversion.

All exceptions will be converted. All known 4xx exceptions (Http404,
PermissionDenied, MultiPartParserError, SuspiciousOperation) will be
converted to the appropriate response, and all other exceptions will be
converted to 500 responses.

This decorator is automatically applied to all middleware to ensure that
no middleware leaks an exception and that the next middleware in the stack
can rely on getting a response instead of an exception.
"""
if asyncio.iscoroutinefunction(get_response):
    @wraps(get_response)
    async def inner(request):
        try:
            response = await get_response(request)
        except Exception as exc:
            response = await sync_to_async(response_for_exception, thread_sensitive=False)(request, exc)
        return response
    return inner
else:
    @wraps(get_response)
    def inner(request):
        try:
            response = get_response(request)
        except Exception as exc:
            response = response_for_exception(request, exc)
        return response
    return inner

def response_for_exception(request, exc):
if isinstance(exc, Http404):
if settings.DEBUG:
response = debug.technical_404_response(request, exc)
else:
response = get_exception_response(request, get_resolver(get_urlconf()), 404, exc)

elif isinstance(exc, PermissionDenied):
    response = get_exception_response(request, get_resolver(get_urlconf()), 403, exc)
    log_response(
        'Forbidden (Permission denied): %s', request.path,
        response=response,
        request=request,
        exc_info=sys.exc_info(),
    )

elif isinstance(exc, MultiPartParserError):
    response = get_exception_response(request, get_resolver(get_urlconf()), 400, exc)
    log_response(
        'Bad request (Unable to parse request body): %s', request.path,
        response=response,
        request=request,
        exc_info=sys.exc_info(),
    )

elif isinstance(exc, BadRequest):
    if settings.DEBUG:
        response = debug.technical_500_response(request, *sys.exc_info(), status_code=400)
    else:
        response = get_exception_response(request, get_resolver(get_urlconf()), 400, exc)
    log_response(
        '%s: %s', str(exc), request.path,
        response=response,
        request=request,
        exc_info=sys.exc_info(),
    )
elif isinstance(exc, SuspiciousOperation):
    if isinstance(exc, (RequestDataTooBig, TooManyFieldsSent)):
        # POST data can't be accessed again, otherwise the original
        # exception would be raised.
        request._mark_post_parse_error()

    # The request logger receives events for any problematic request
    # The security logger receives events for all SuspiciousOperations
    security_logger = logging.getLogger('django.security.%s' % exc.__class__.__name__)
    security_logger.error(
        str(exc),
        extra={'status_code': 400, 'request': request},
    )
    if settings.DEBUG:
        response = debug.technical_500_response(request, *sys.exc_info(), status_code=400)
    else:
        response = get_exception_response(request, get_resolver(get_urlconf()), 400, exc)

elif isinstance(exc, SystemExit):
    # Allow sys.exit() to actually exit. See tickets #1023 and #4701
    raise

else:
    signals.got_request_exception.send(sender=None, request=request)
    response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
    log_response(
        '%s: %s', response.reason_phrase, request.path,
        response=response,
        request=request,
        exc_info=sys.exc_info(),
    )

# Force a TemplateResponse to be rendered.
if not getattr(response, 'is_rendered', True) and callable(getattr(response, 'render', None)):
    response = response.render()

return response

def get_exception_response(request, resolver, status_code, exception):
try:
callback = resolver.resolve_error_handler(status_code)
response = callback(request, exception=exception)
except Exception:
signals.got_request_exception.send(sender=None, request=request)
response = handle_uncaught_exception(request, resolver, sys.exc_info())

return response

def handle_uncaught_exception(request, resolver, exc_info):
“”"
Processing for any otherwise uncaught exceptions (those that will
generate HTTP 500 responses).
“”"
if settings.DEBUG_PROPAGATE_EXCEPTIONS:
raise

if settings.DEBUG:
    return debug.technical_500_response(request, *exc_info)

# Return an HttpResponse that displays a friendly error message.
callback = resolver.resolve_error_handler(500)
return callback(request)

First, enclose your blocks of code between lines of three backtick - ` characters. You’ll have a line of ```, then the code, then another line of ```. This prevents the forum software from reformatting the code. (You can enclose each block of code separately if you want to add text between the blocks.

It appears to me that the first function (get_models_for_count) is going to return a list with two numbers. For discussion purposes, let’s assume right now that it returns [5, 7].

Those are the parameters that you are passing into the get_queryset call, so effectively you’re issuing the call qs = list(self.get_queryset().annotate(5, 7)). That doesn’t appear to me to be what you want to do.

1 Like

Regarding the KeyError exception, the message indicates it’s Сматфоны, but CATEGORY_NAME_COUNT_NAME only defines:

CATEGORY_NAME_COUNT_NAME = {
    'Ноутбуки': 'notebook__count',
    'Смартфоны': 'smartphone__count'
}

Given the similarities, I’m betting the issue is with Смартфоны != Сматфоны.

1 Like

Thank you for pointing out this problem to me, it fixed everything.