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)