Old question, but I hope this helps someone in the future. The accepted answer doesn’t really answer the original question…
You can do this with django rest framework easily by raising ApiException:
from rest_framework.exceptions import APIException
try:
...
except ...:
raise APIException('custom exception message')
This will return a response with status 500 from your view. Pretty useful if you are calling another function from your API and you don’t want to manage return values from this function to decide if returning a response with status 500.
You can use it like this:
raise ApiException
And the default response message (at the time of writing this) will be ‘A server error occurred.’.
There’s a few predefined ApiException subclasses to raise different kinds of errors, check the file rest_framework.exceptions, if you need one that is not in there, you can extend ApiException like this:
from rest_framework.exceptions import APIException
class YourCustomApiExceptionName(APIException):
def __init__(self, status, detail):
self.status_code = status
self.detail = detail
Usage:
raise YourCustomApiExceptionName(100, 'continue')
You can also define custom status and detail but wouldn’t make much sense in most cases.
-
Getting Help
-
el
-
es
-
fr
-
id
-
it
-
ja
-
ko
-
pl
-
pt-br
-
zh-hans
- Language: en
-
1.8
-
1.10
-
1.11
-
2.0
-
2.1
-
2.2
-
3.0
-
3.1
-
3.2
-
4.0
-
4.2
-
dev
-
Documentation version:
4.1
Built-in Views¶
Several of Django’s built-in views are documented in
Writing views as well as elsewhere in the documentation.
Serving files in development¶
-
static.serve(request, path, document_root, show_indexes=False)¶
There may be files other than your project’s static assets that, for
convenience, you’d like to have Django serve for you in local development.
The serve() view can be used to serve any directory
you give it. (This view is not hardened for production use and should be
used only as a development aid; you should serve these files in production
using a real front-end web server).
The most likely example is user-uploaded content in MEDIA_ROOT.
django.contrib.staticfiles is intended for static assets and has no
built-in handling for user-uploaded files, but you can have Django serve your
MEDIA_ROOT by appending something like this to your URLconf:
from django.conf import settings from django.urls import re_path from django.views.static import serve # ... the rest of your URLconf goes here ... if settings.DEBUG: urlpatterns += [ re_path(r'^media/(?P<path>.*)$', serve, { 'document_root': settings.MEDIA_ROOT, }), ]
Note, the snippet assumes your MEDIA_URL has a value of
'media/'. This will call the serve() view,
passing in the path from the URLconf and the (required) document_root
parameter.
Since it can become a bit cumbersome to define this URL pattern, Django
ships with a small URL helper function static()
that takes as parameters the prefix such as MEDIA_URL and a dotted
path to a view, such as 'django.views.static.serve'. Any other function
parameter will be transparently passed to the view.
Error views¶
Django comes with a few views by default for handling HTTP errors. To override
these with your own custom views, see Customizing error views.
The 404 (page not found) view¶
-
defaults.page_not_found(request, exception, template_name=‘404.html’)¶
When you raise Http404 from within a view, Django loads a
special view devoted to handling 404 errors. By default, it’s the view
django.views.defaults.page_not_found(), which either produces a “Not
Found” message or loads and renders the template 404.html if you created it
in your root template directory.
The default 404 view will pass two variables to the template: request_path,
which is the URL that resulted in the error, and exception, which is a
useful representation of the exception that triggered the view (e.g. containing
any message passed to a specific Http404 instance).
Three things to note about 404 views:
- The 404 view is also called if Django doesn’t find a match after
checking every regular expression in the URLconf. - The 404 view is passed a
RequestContextand
will have access to variables supplied by your template context
processors (e.g.MEDIA_URL). - If
DEBUGis set toTrue(in your settings module), then
your 404 view will never be used, and your URLconf will be displayed
instead, with some debug information.
The 500 (server error) view¶
-
defaults.server_error(request, template_name=‘500.html’)¶
Similarly, Django executes special-case behavior in the case of runtime errors
in view code. If a view results in an exception, Django will, by default, call
the view django.views.defaults.server_error, which either produces a
“Server Error” message or loads and renders the template 500.html if you
created it in your root template directory.
The default 500 view passes no variables to the 500.html template and is
rendered with an empty Context to lessen the chance of additional errors.
If DEBUG is set to True (in your settings module), then
your 500 view will never be used, and the traceback will be displayed
instead, with some debug information.
The 403 (HTTP Forbidden) view¶
-
defaults.permission_denied(request, exception, template_name=‘403.html’)¶
In the same vein as the 404 and 500 views, Django has a view to handle 403
Forbidden errors. If a view results in a 403 exception then Django will, by
default, call the view django.views.defaults.permission_denied.
This view loads and renders the template 403.html in your root template
directory, or if this file does not exist, instead serves the text
“403 Forbidden”, as per RFC 7231#section-6.5.3 (the HTTP 1.1 Specification).
The template context contains exception, which is the string
representation of the exception that triggered the view.
django.views.defaults.permission_denied is triggered by a
PermissionDenied exception. To deny access in a
view you can use code like this:
from django.core.exceptions import PermissionDenied def edit(request, pk): if not request.user.is_staff: raise PermissionDenied # ...
The 400 (bad request) view¶
-
defaults.bad_request(request, exception, template_name=‘400.html’)¶
When a SuspiciousOperation is raised in Django,
it may be handled by a component of Django (for example resetting the session
data). If not specifically handled, Django will consider the current request a
‘bad request’ instead of a server error.
django.views.defaults.bad_request, is otherwise very similar to the
server_error view, but returns with the status code 400 indicating that
the error condition was the result of a client operation. By default, nothing
related to the exception that triggered the view is passed to the template
context, as the exception message might contain sensitive information like
filesystem paths.
bad_request views are also only used when DEBUG is False.
Back to Top
Learn how to use the Django custom 500 error template page. In this tutorial, you will learn how to create a custom page for internal server errors. And learn how to handle errors in Django with built-in views. Handler 500 is the built-in view. This will allow us to handle the 500 internal server errors using the custom template created by us.
Requirements :
pip install django
This command will install the latest Django package into your local machine.
Firstly Create a Django Project :
python -admin django startproject project
This command will create new project.
Navigate to Project folder :
cd project #projectname
This will change the current directory of the terminal to the project directory
Secondly Creating app with Demo app :
py manage.py startapp demo
Create a demo app for the Django project we have created.
Thirdly Create Urls.py in Demo app
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name="home")
]
Here, We are creating the routing paths for the home view this will render out the Html page we have created for the model form. However the ” will represent the localhost path it will render the Html template as the homepage for the project on the localhost address. i.e. 127.0.0.1:8000. Get reference from Documentation
Creating views in demo app :
from django.shortcuts import render
# Create your views here.
def home(request):
return render(request, 'home.html')
def error_500(request):
return render(request, '500.html')
def check():
pass
Here we are creating the 3 views home and error_500. The home view will return the home.html page. And the error_500 view will return our custom 500 page which is a 500.html page. And finally check view is a dummy view which returns nothing. Hence it should raise an internal server error. This check view is only for checking 500 page status and optional.
Adding view handler to the main URLs :
from django.conf.urls import handler404, handler500
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('demo.urls'))
]
handler500 = 'demo.views.error_500'
Here the built-in handler will be overridden with the view in the demo app which is error_500. Nothing but the default template of the 500 internal server error given by Django will be modified by the 500.html in our project.
Change the Settings.py
# SECURITY WARNING: don't run with debug turned on in production! DEBUG = False ALLOWED_HOSTS = ['*']
Here we are changing the Settings.py file of the project we have created because. We have to change the DEBUG as False nothing but we are turning off the Django security to check the server. And again we need to modify the allowed host with ‘*’ because it allows every host user to access the content and render the handlers properly on localhost.
500 HTML template :
<html> <body> <h1>Internal server Error 500</h1> </body> </html>
Output :

Hence this is how we can use the Django custom 500 error template page.
- 1. Кастомизация ошибок 404, 500
- 2. Кастомизация ошибки 403
Многие ресурсы имеют оформленные страницы ошибок, если происходит сбой в обработке запроса от клиента.
Для начала на сайте была сделана кастомизация наиболее часто возникающих ошибок, другие при отладке пока не попадались, но всё впереди.
Как объявлено в заголовке статьи, кастомизированы был следующие ошибки:
- 403 — Ошибка авторизации, доступ запрещён.
- 404 — Страница не найдена;
- 500 — Внутренняя ошибка сервера;
Кастомизация ошибок 404, 500
Для кастомизации ошибок 404 и 500 необходимо написать обработчики запросов, и достаточно написать их представления в виде метода.
В шаблоны добавляем свои кастомизированные html файлы, то есть:
- error404.html
- error500.html
Модуль, в котором реализованы представления для данного сайта — это
home.
В шаблонах этого же модуля помещены сами шаблоны кастомизированных ошибок.
В файле
urls.py
главного модуля сайта переопределяем обработчики по умолчанию:
- handler404
- handler500
В коде это выглядит так:
from home.views import e_handler404, e_handler500 handler404 = e_handler404 handler500 = e_handler500Опишем представления в файле
views.py
модуля
home:
from django.shortcuts import render_to_response from django.template import RequestContext def e_handler404(request): context = RequestContext(request) response = render_to_response('error404.html', context) response.status_code = 404 return response def e_handler500(request): context = RequestContext(request) response = render_to_response('error500.html', context) response.status_code = 500 return responseКастомизация ошибки 403
Ошибка 403 возникает в том случае, когда не авторизованный пользователь пытается получить доступ к той части сайта, в которую доступ разрешён только авторизованным пользователям.
В Django это достигается за счёт проверки статуса пользователя и добавления на страницы защитного токена, механизм
CSRF.
Данная ошибка может возникнуть и в том случае, если пользователь авторизован, но совершает действия, при которых требуется проверка токена CSRF, а сам токен был потерян или не верен. Дело в том, что для корректности работы токена, необходимо добавлять в шаблоне в формах специальный тег:{% csrf_token %}В него и будет подставляться токен, но просто добавить в шаблон, его не достаточно. Прежде, чем начать рендер шаблон, необходимо добавить токен в контекст, который будет передан в шаблон. То есть,
from django.template.context_processors import csrf from django.shortcuts import render_to_response def any_request(request): context = {} context.update(csrf(request)) ... return render_to_response('any_request.html', context=context)Ну а теперь ближе к непосредственно кастомизации. Для работы csrf необходимо, чтобы в файле
settings.py
добавлен модуль csrf и указано представление, которое будет заниматься обработкой данной ошибки:MIDDLEWARE = [ ... 'django.middleware.csrf.CsrfViewMiddleware', ... ] CSRF_FAILURE_VIEW = 'home.views.csrf_failure'В шаблонах добавим
error403.html,
а в файле
views.py
пропишем обработчик представления.def csrf_failure(request, reason=""): context = RequestContext(request) response = render_to_response('error403.html', context) response.status_code = 403 return responseДля
Django
рекомендуюVDS-сервера хостера Timeweb
.
exceptions.py
Exceptions… allow error handling to be organized cleanly in a central or high-level place within the program structure.
— Doug Hellmann, Python Exception Handling Techniques
Exception handling in REST framework views
REST framework’s views handle various exceptions, and deal with returning appropriate error responses.
The handled exceptions are:
- Subclasses of
APIExceptionraised inside REST framework. - Django’s
Http404exception. - Django’s
PermissionDeniedexception.
In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.
Most error responses will include a key detail in the body of the response.
For example, the following request:
DELETE http://api.example.com/foo/bar HTTP/1.1
Accept: application/json
Might receive an error response indicating that the DELETE method is not allowed on that resource:
HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Content-Length: 42
{"detail": "Method 'DELETE' not allowed."}
Validation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the «non_field_errors» key, or whatever string value has been set for the NON_FIELD_ERRORS_KEY setting.
An example validation error might look like this:
HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 94
{"amount": ["A valid integer is required."], "description": ["This field may not be blank."]}
Custom exception handling
You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.
The function must take a pair of arguments, the first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 ‘server error’ response.
For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so:
HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Content-Length: 62
{"status_code": 405, "detail": "Method 'DELETE' not allowed."}
In order to alter the style of the response, you could write the following custom exception handler:
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first,
# to get the standard error response.
response = exception_handler(exc, context)
# Now add the HTTP status code to the response.
if response is not None:
response.data['status_code'] = response.status_code
return response
The context argument is not used by the default handler, but can be useful if the exception handler needs further information such as the view currently being handled, which can be accessed as context['view'].
The exception handler must also be configured in your settings, using the EXCEPTION_HANDLER setting key. For example:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}
If not specified, the 'EXCEPTION_HANDLER' setting defaults to the standard exception handler provided by REST framework:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}
Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the HTTP_400_BAD_REQUEST responses that are returned by the generic views when serializer validation fails.
API Reference
APIException
Signature: APIException()
The base class for all exceptions raised inside an APIView class or @api_view.
To provide a custom exception, subclass APIException and set the .status_code, .default_detail, and default_code attributes on the class.
For example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the «503 Service Unavailable» HTTP response code. You could do this like so:
from rest_framework.exceptions import APIException
class ServiceUnavailable(APIException):
status_code = 503
default_detail = 'Service temporarily unavailable, try again later.'
default_code = 'service_unavailable'
Inspecting API exceptions
There are a number of different properties available for inspecting the status
of an API exception. You can use these to build custom exception handling
for your project.
The available attributes and methods are:
.detail— Return the textual description of the error..get_codes()— Return the code identifier of the error..get_full_details()— Return both the textual description and the code identifier.
In most cases the error detail will be a simple item:
>>> print(exc.detail)
You do not have permission to perform this action.
>>> print(exc.get_codes())
permission_denied
>>> print(exc.get_full_details())
{'message':'You do not have permission to perform this action.','code':'permission_denied'}
In the case of validation errors the error detail will be either a list or
dictionary of items:
>>> print(exc.detail)
{"name":"This field is required.","age":"A valid integer is required."}
>>> print(exc.get_codes())
{"name":"required","age":"invalid"}
>>> print(exc.get_full_details())
{"name":{"message":"This field is required.","code":"required"},"age":{"message":"A valid integer is required.","code":"invalid"}}
ParseError
Signature: ParseError(detail=None, code=None)
Raised if the request contains malformed data when accessing request.data.
By default this exception results in a response with the HTTP status code «400 Bad Request».
AuthenticationFailed
Signature: AuthenticationFailed(detail=None, code=None)
Raised when an incoming request includes incorrect authentication.
By default this exception results in a response with the HTTP status code «401 Unauthenticated», but it may also result in a «403 Forbidden» response, depending on the authentication scheme in use. See the authentication documentation for more details.
NotAuthenticated
Signature: NotAuthenticated(detail=None, code=None)
Raised when an unauthenticated request fails the permission checks.
By default this exception results in a response with the HTTP status code «401 Unauthenticated», but it may also result in a «403 Forbidden» response, depending on the authentication scheme in use. See the authentication documentation for more details.
PermissionDenied
Signature: PermissionDenied(detail=None, code=None)
Raised when an authenticated request fails the permission checks.
By default this exception results in a response with the HTTP status code «403 Forbidden».
NotFound
Signature: NotFound(detail=None, code=None)
Raised when a resource does not exists at the given URL. This exception is equivalent to the standard Http404 Django exception.
By default this exception results in a response with the HTTP status code «404 Not Found».
MethodNotAllowed
Signature: MethodNotAllowed(method, detail=None, code=None)
Raised when an incoming request occurs that does not map to a handler method on the view.
By default this exception results in a response with the HTTP status code «405 Method Not Allowed».
NotAcceptable
Signature: NotAcceptable(detail=None, code=None)
Raised when an incoming request occurs with an Accept header that cannot be satisfied by any of the available renderers.
By default this exception results in a response with the HTTP status code «406 Not Acceptable».
Signature: UnsupportedMediaType(media_type, detail=None, code=None)
Raised if there are no parsers that can handle the content type of the request data when accessing request.data.
By default this exception results in a response with the HTTP status code «415 Unsupported Media Type».
Throttled
Signature: Throttled(wait=None, detail=None, code=None)
Raised when an incoming request fails the throttling checks.
By default this exception results in a response with the HTTP status code «429 Too Many Requests».
ValidationError
Signature: ValidationError(detail, code=None)
The ValidationError exception is slightly different from the other APIException classes:
- The
detailargument is mandatory, not optional. - The
detailargument may be a list or dictionary of error details, and may also be a nested data structure. By using a dictionary, you can specify field-level errors while performing object-level validation in thevalidate()method of a serializer. For example.raise serializers.ValidationError({'name': 'Please enter a valid name.'}) - By convention you should import the serializers module and use a fully qualified
ValidationErrorstyle, in order to differentiate it from Django’s built-in validation error. For example.raise serializers.ValidationError('This field must be an integer value.')
The ValidationError class should be used for serializer and field validation, and by validator classes. It is also raised when calling serializer.is_valid with the raise_exception keyword argument:
serializer.is_valid(raise_exception=True)
The generic views use the raise_exception=True flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above.
By default this exception results in a response with the HTTP status code «400 Bad Request».
Generic Error Views
Django REST Framework provides two error views suitable for providing generic JSON 500 Server Error and
400 Bad Request responses. (Django’s default error views provide HTML responses, which may not be appropriate for an
API-only application.)
Use these as per Django’s Customizing error views documentation.
rest_framework.exceptions.server_error
Returns a response with status code 500 and application/json content type.
Set as handler500:
handler500 = 'rest_framework.exceptions.server_error'
rest_framework.exceptions.bad_request
Returns a response with status code 400 and application/json content type.
Set as handler400:
handler400 = 'rest_framework.exceptions.bad_request'
Third party packages
The following third-party packages are also available.
DRF Standardized Errors
The drf-standardized-errors package provides an exception handler that generates the same format for all 4xx and 5xx responses. It is a drop-in replacement for the default exception handler and allows customizing the error response format without rewriting the whole exception handler. The standardized error response format is easier to document and easier to handle by API consumers.
Я пытаюсь настроить регистрацию ошибок электронной почты и хочу проверить это.
Какой простой способ вызвать ошибку 500 в Django? Это на удивление еще не обсуждалось здесь.
2 ответа
Лучший ответ
Такое тестовое представление будет работать:
from django.http import HttpResponse
def my_test_500_view(request):
# Return an "Internal Server Error" 500 response code.
return HttpResponse(status=500)
Или используйте запеченный в классе ошибок:
from django.http import HttpResponseServerError
def my_test_500_view(request):
# Return an "Internal Server Error" 500 response code.
return HttpResponseServerError()
37
agconti
17 Апр 2018 в 13:21
Подбор подходящего Exception — самый надежный способ проверить это. Возвращение HttpResponse любого разнообразия, как в ответе @agconti, не позволит вам проверить поведение обработки ошибок . Вы просто увидите пустую страницу. Вызов исключения вызывает как правильный код ответа, так и внутреннее поведение Django, которое вы ожидаете, с «настоящей» ошибкой.
Код ответа 500 представляет сервер, не зная, что делать. Самый простой способ — записать в свой тест или представление теста raise Exception('Make response code 500!').
Большинство других ошибок должно возникать с исключениями, предназначенными для запуска определенных кодов ответов. Вот полный список исключений Django, который вы можете поднять.
13
Shaun Overton
16 Июл 2018 в 13:02
I have a 500.html template which gets loaded whenever my app explodes but I wanted to know if there’s any way I can output the exception’s message in the template?
So if I do this:
raise Exception("You broke it!")
This will load 500.html when the DEBUG flag is set to True but how can I access the exception message in the template? Something like:
{{ exception.message }}
Many thanks.
G
asked May 31, 2011 at 15:55
Have a look at this answer:
How do I include a stacktrace in my Django 500.html page?
It’s not good to pass the exception to your template/user as it might show some inside workings that you don’t want available to the outside, but if you really need to, you could write your own 500 view, grabbing the exception and passing it to your 500 template
views.py
def custom_500(request):
t = loader.get_template('500.html')
type, value, tb = sys.exc_info(),
return HttpResponseServerError(t.render(Context({
'exception_value': value,
})))
somewhere in urls.py
handler500 = 'mysite.views.my_custom_error_view'
template
{{ exception_value }}
more about it here: https://docs.djangoproject.com/en/1.6/topics/http/views/#the-500-server-error-view
answered May 31, 2011 at 16:11
Timmy O’MahonyTimmy O’Mahony
52.2k18 gold badges153 silver badges174 bronze badges
2
I know this is an old thread, but I just wanna to make it clear:
The answer is correct if you want a custon view! The default view will load a 500.html (also 404.html and others), from the main templates directory of your project if it’s there.
So, if all you need is to change static page content, like insert some images in your error page, all you have to do is to create a template file at this place.
answered Dec 11, 2013 at 0:26
Gustavo VargasGustavo Vargas
2,4492 gold badges23 silver badges32 bronze badges
I have a 500.html template which gets loaded whenever my app explodes but I wanted to know if there’s any way I can output the exception’s message in the template?
So if I do this:
raise Exception("You broke it!")
This will load 500.html when the DEBUG flag is set to True but how can I access the exception message in the template? Something like:
{{ exception.message }}
Many thanks.
G
asked May 31, 2011 at 15:55
Have a look at this answer:
How do I include a stacktrace in my Django 500.html page?
It’s not good to pass the exception to your template/user as it might show some inside workings that you don’t want available to the outside, but if you really need to, you could write your own 500 view, grabbing the exception and passing it to your 500 template
views.py
def custom_500(request):
t = loader.get_template('500.html')
type, value, tb = sys.exc_info(),
return HttpResponseServerError(t.render(Context({
'exception_value': value,
})))
somewhere in urls.py
handler500 = 'mysite.views.my_custom_error_view'
template
{{ exception_value }}
more about it here: https://docs.djangoproject.com/en/1.6/topics/http/views/#the-500-server-error-view
answered May 31, 2011 at 16:11
Timmy O’MahonyTimmy O’Mahony
52.2k18 gold badges153 silver badges174 bronze badges
2
I know this is an old thread, but I just wanna to make it clear:
The answer is correct if you want a custon view! The default view will load a 500.html (also 404.html and others), from the main templates directory of your project if it’s there.
So, if all you need is to change static page content, like insert some images in your error page, all you have to do is to create a template file at this place.
answered Dec 11, 2013 at 0:26
Gustavo VargasGustavo Vargas
2,4492 gold badges23 silver badges32 bronze badges
Исключения¶
Исключения… позволяют чисто организовать обработку ошибок в центральном или высокоуровневом месте в структуре программы.
‒ Doug Hellmann, Python Exception Handling Techniques
Представления фреймворка REST обрабатывают различные исключения и возвращают соответствующие ответы на ошибки.
Обрабатываемыми исключениями являются:
-
Подклассы
APIException, поднятые внутри фреймворка REST. -
Исключение Django
Http404. -
Исключение Django
PermissionDenied.
В каждом случае фреймворк REST возвращает ответ с соответствующим кодом состояния и типом содержимого. В теле ответа будут содержаться любые дополнительные сведения о характере ошибки.
Большинство ответов на ошибки будут содержать ключ detail в теле ответа.
Например, следующий запрос:
DELETE http://api.example.com/foo/bar HTTP/1.1 Accept: application/json
Может быть получен ответ об ошибке, указывающий на то, что метод DELETE не разрешен на данном ресурсе:
HTTP/1.1 405 Method Not Allowed Content-Type: application/json Content-Length: 42 {"detail": "Method 'DELETE' not allowed."}
Ошибки валидации обрабатываются несколько иначе, и в качестве ключей в ответе будут указаны имена полей. Если ошибка валидации не относится к конкретному полю, то будет использован ключ «non_field_errors» или любое строковое значение, установленное для параметра NON_FIELD_ERRORS_KEY.
Пример ошибки валидации может выглядеть следующим образом:
HTTP/1.1 400 Bad Request Content-Type: application/json Content-Length: 94 {"amount": ["A valid integer is required."], "description": ["This field may not be blank."]}
Пользовательская обработка исключений¶
Вы можете реализовать пользовательскую обработку исключений, создав функцию-обработчик, которая преобразует исключения, возникающие в представлениях вашего API, в объекты ответа. Это позволит вам контролировать стиль ответов на ошибки, используемый вашим API.
Функция должна принимать пару аргументов, первый из которых — обрабатываемое исключение, а второй — словарь, содержащий любой дополнительный контекст, например, обрабатываемое в данный момент представление. Функция обработчика исключения должна либо вернуть объект Response, либо вернуть None, если исключение не может быть обработано. Если обработчик возвращает None, то исключение будет повторно поднято и Django вернет стандартный ответ HTTP 500 „server error“.
Например, вы можете захотеть убедиться, что все ответы на ошибки включают код состояния HTTP в теле ответа, например, так:
HTTP/1.1 405 Method Not Allowed Content-Type: application/json Content-Length: 62 {"status_code": 405, "detail": "Method 'DELETE' not allowed."}
Чтобы изменить стиль ответа, вы можете написать следующий пользовательский обработчик исключений:
from rest_framework.views import exception_handler def custom_exception_handler(exc, context): # Call REST framework's default exception handler first, # to get the standard error response. response = exception_handler(exc, context) # Now add the HTTP status code to the response. if response is not None: response.data['status_code'] = response.status_code return response
Аргумент context не используется обработчиком по умолчанию, но может быть полезен, если обработчику исключения нужна дополнительная информация, например, обрабатываемое в данный момент представление, доступ к которому можно получить в виде context['view'].
Обработчик исключений также должен быть настроен в ваших настройках, используя клавишу настройки EXCEPTION_HANDLER. Например:
REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler' }
Если параметр 'EXCEPTION_HANDLER' не указан, то по умолчанию используется стандартный обработчик исключений, предоставляемый фреймворком REST:
REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler' }
Обратите внимание, что обработчик исключений будет вызываться только для ответов, сгенерированных поднятыми исключениями. Он не будет использоваться для любых ответов, возвращаемых непосредственно представлением, например, ответов HTTP_400_BAD_REQUEST, которые возвращаются общими представлениями при неудачной проверке сериализатора.
Справочник по API¶
APIException¶
Подпись: APIException()
базовый класс для всех исключений, возникающих внутри класса APIView или @api_view.
Чтобы обеспечить пользовательское исключение, подкласс APIException и установите атрибуты .status_code , .default_detail , и default_code на класс.
Например, если ваш API полагается на сторонний сервис, который иногда может быть недоступен, вы можете захотеть реализовать исключение для кода ответа HTTP «503 Service Unavailable». Это можно сделать следующим образом:
from rest_framework.exceptions import APIException class ServiceUnavailable(APIException): status_code = 503 default_detail = 'Service temporarily unavailable, try again later.' default_code = 'service_unavailable'
Проверка исключений API¶
Существует ряд различных свойств, доступных для проверки состояния исключения API. Вы можете использовать их для создания пользовательской обработки исключений в вашем проекте.
Доступными атрибутами и методами являются:
-
.detail— Возвращает текстовое описание ошибки. -
.get_codes()— Возвращает идентификатор кода ошибки. -
.get_full_details()— Возвращает как текстовое описание, так и идентификатор кода.
В большинстве случаев деталь ошибки будет простым элементом:
>>> print(exc.detail) You do not have permission to perform this action. >>> print(exc.get_codes()) permission_denied >>> print(exc.get_full_details()) {'message':'You do not have permission to perform this action.','code':'permission_denied'}
В случае ошибок валидации деталь ошибки будет представлять собой список или словарь элементов:
>>> print(exc.detail) {"name":"This field is required.","age":"A valid integer is required."} >>> print(exc.get_codes()) {"name":"required","age":"invalid"} >>> print(exc.get_full_details()) {"name":{"message":"This field is required.","code":"required"},"age":{"message":"A valid integer is required.","code":"invalid"}}
ParseError¶
Подпись: ParseError(detail=None, code=None)
Возникает, если запрос содержит неправильно сформированные данные при доступе к request.data.
По умолчанию это исключение приводит к ответу с кодом состояния HTTP «400 Bad Request».
AuthenticationFailed¶
Подпись: AuthenticationFailed(detail=None, code=None)
Возникает, когда входящий запрос содержит неправильную аутентификацию.
По умолчанию это исключение приводит к ответу с кодом состояния HTTP «401 Unauthenticated», но оно также может привести к ответу «403 Forbidden», в зависимости от используемой схемы аутентификации. Более подробную информацию см. в authentication documentation.
NotAuthenticated¶
Подпись: NotAuthenticated(detail=None, code=None)
Возникает, когда неаутентифицированный запрос не прошел проверку на разрешение.
По умолчанию это исключение приводит к ответу с кодом состояния HTTP «401 Unauthenticated», но оно также может привести к ответу «403 Forbidden», в зависимости от используемой схемы аутентификации. Более подробную информацию см. в authentication documentation.
PermissionDenied¶
Подпись: PermissionDenied(detail=None, code=None)
Возникает, когда аутентифицированный запрос не прошел проверку на разрешение.
По умолчанию это исключение приводит к ответу с кодом состояния HTTP «403 Forbidden».
NotFound¶
Подпись: NotFound(detail=None, code=None)
Возникает, когда ресурс не существует по заданному URL. Это исключение эквивалентно стандартному исключению Django Http404.
По умолчанию это исключение приводит к ответу с кодом состояния HTTP «404 Not Found».
MethodNotAllowed¶
Подпись: MethodNotAllowed(method, detail=None, code=None)
Возникает, когда происходит входящий запрос, который не сопоставлен с методом-обработчиком на представлении.
По умолчанию это исключение приводит к ответу с кодом состояния HTTP «405 Method Not Allowed».
Неприемлемо¶
Подпись: NotAcceptable(detail=None, code=None)
Возникает, когда поступает запрос с заголовком Accept, который не может быть удовлетворен ни одним из доступных рендереров.
По умолчанию это исключение приводит к ответу с кодом состояния HTTP «406 Not Acceptable».
Дросселированный¶
Подпись: Throttled(wait=None, detail=None, code=None)
Возникает, когда входящий запрос не проходит проверку на дросселирование.
По умолчанию это исключение приводит к ответу с кодом состояния HTTP «429 Too Many Requests».
ValidationError¶
Подпись: ValidationError(detail, code=None)
Исключение ValidationError несколько отличается от других классов APIException:
-
Аргумент
detailявляется обязательным, а не опциональным. -
Аргумент
detailможет представлять собой список или словарь сведений об ошибках, а также может быть вложенной структурой данных. Используя словарь, вы можете указать ошибки на уровне полей при выполнении проверки на уровне объектов в методеvalidate()сериализатора. Например.raise serializers.ValidationError({'name': 'Please enter a valid name.'}) -
По соглашению вы должны импортировать модуль serializers и использовать полностью квалифицированный стиль
ValidationError, чтобы отличить его от встроенной ошибки валидации Django. Например.raise serializers.ValidationError('This field must be an integer value.')
Класс ValidationError следует использовать для сериализатора и валидации полей, а также классами валидаторов. Он также возникает при вызове serializer.is_valid с аргументом ключевого слова raise_exception:
serializer.is_valid(raise_exception=True)
Общие представления используют флаг raise_exception=True, что означает, что вы можете переопределить стиль ответов на ошибки валидации глобально в вашем API. Для этого используйте пользовательский обработчик исключений, как описано выше.
По умолчанию это исключение приводит к ответу с кодом состояния HTTP «400 Bad Request».
Общие представления ошибок¶
Django REST Framework предоставляет два представления ошибок, подходящих для предоставления общих JSON 500 Server Error и 400 Bad Request ответов. (Стандартные представления ошибок Django предоставляют ответы в формате HTML, что может не подойти для приложения, использующего только API).
Используйте их в соответствии с Django’s Customizing error views documentation.
rest_framework.exceptions.server_error¶
Возвращает ответ с кодом состояния 500 и типом содержимого application/json.
Установить как handler500 :
handler500 = 'rest_framework.exceptions.server_error'
rest_framework.exceptions.bad_request¶
Возвращает ответ с кодом состояния 400 и типом содержимого application/json.
Установить как handler400 :
handler400 = 'rest_framework.exceptions.bad_request'
Вернуться на верх
Я пытаюсь настроить регистрацию ошибок электронной почты, и я хочу проверить его.
Какой простой способ вызвать ошибку 500 в Django? Это удивительно еще не обсуждалось.
09 июль 2014, в 19:46
Поделиться
Источник
1 ответ
Возможно, будет работать тестовое представление:
from django.http import HttpResponse
def my_test_500_view(request):
# Return an "Internal Server Error" 500 response code.
return HttpResponse(status=500)
или менее растяжимым способом:
from django.http import HttpResponseServerError
def my_test_500_view(request):
# Return an "Internal Server Error" 500 response code.
return HttpResponseServerError()
agconti
09 июль 2014, в 18:24
Поделиться
Ещё вопросы
- 0Щелчок мыши не вызывает несколько действий в JavaScript
- 0Выполнить jquery при первом посещении страницы
- 0Почему опасно отображать пользовательский HTML или Javascript?
- 1Визуализация угловых компонентов материала с помощью ComponentFactoryResolver
- 1Проверьте переполнение при реализации питания
- 0Добавьте правило брандмауэра в базу данных Azure для сервера MySQL из powershell
- 0Очистить выравнивание CSS-рамки
- 0Центрирование внутри элемента <div>
- 1проблема с картой мира D3js и шириной элемента группы svg
- 0Как получить большую фотографию в Instagram
- 1Microsoft.TeamFoundation создать проект
- 0jQuery плагин котельная плита — частный метод с ограниченной областью?
- 0Манипулирование массивами дат в PHP
- 1Вызов метода Post веб-службы
- 0Какой подход сохранения свойства модели лучше?
- 0MySQL-запрос, который ограничивает первое соединение определенным количеством строк
- 2Где хранить пароль / логин-путь в MariaDB (эквивалент для mysql-config-editor)?
- 1Генерация мультитач MotionEvents для тестирования
- 0Angularjs выбирает поля
- 0Вывести теги скриптов без jQuery, избегая выполнения
- 0Visual C ++ 2010 ошибка. Система не может найти файл, указанный при запуске LibICP
- 1Параметризованные генераторы при использовании tf.data.Dataset.from_generator ()
- 1MVC3 Пользовательский атрибут проверки, который сравнивает допустимые минимальные и максимальные значения
- 1Объективный эквивалент C байта в C #
- 1Автоматизация Webdriver — Невозможно найти элемент, используя xpath (на странице эталонных тестов Octane 2.0)
- 1Разделить список объектов
- 0Использование Masonry.js на jQuery генерирует div
- 0Разделить строку, используя специальные параметры
- 0Дата от весны до сети как отметка времени с использованием Jakson
- 0Перенаправлять посетителей на основе текущего URL
- 0Есть ли способ использовать Qt и C ++ для взаимодействия с веб-страницей?
- 0Magento php расчет по цене
- 0использование jQuery .each в переменной javascript перед добавлением на экран
- 0SQL-запрос в цикле накапливает каждый цикл
- 1System.Management.Automation.Remoting.PSRemotingTransportException: доступ запрещен.
- 1Сравните растровые изображения на холсте
- 1Метеор Курурин Пагинация не работает
- 0Отображение изображения в браузере
- 1Случайные числа меняются при изменении ориентации
- 1com.microsoft.sqlserver.jdbc.SQLServerException: сбой входа для пользователя ‘sa’
- 1Обновление данных в datagridview и графическом окне одновременно C #
- 1Холст был испорчен данными локального происхождения.
- 0Не могу заставить CSS работать над добавленной таблицей
- 1Eclipse показывает ошибку неиспользованного импорта, но все импорта необходимы
- 0Magento добавить пользовательский столбец в Order
- 0Создавайте cookie, используя ionic angularjs, и сохраняйте cookie в течение длительного времени
- 1приложение для Android убито сразу после запуска
- 1Vector сохраняет один и тот же класс объектов для всех ящиков в Java
- 1Получение местоположения сетки во время выполнения в codebehind
- 1Подключение приложения Android к HTTP-серверу