First of all, you should think about what errors you want to identify:
Typically, 4xx errors (client-side errors) are uncovered, so the user can correct the request.
On the other hand, 5xx errors (Errors that are related to the server side) are usually provided only without information. In my opinion, for those with whom you should use tools such as Sentry , track and fix these errors that may have security issues built into them.
With that in mind, in my opinion, for the correct Ajax request, you must return a status code, and then some json, in order to understand what happened, like a message and explanation (when applicable).
If your goal is to use ajax to send information, I suggest setting form for what you want. Thus, you easily go through the verification process. I guess the point is in this example.
First - Is the query correct?
def test_view(request): message = None explanation = None status_code = 500
Second - Are there any errors in the form?
form = TestForm(request.POST) if form.is_valid(): ... else: message = "The form has errors" explanation = form.errors.as_data()
You can even get the error field by field so that you can better represent it in the form itself.
Third . Let me handle the request
try: test_method(form.cleaned_data) except `PermissionError` as e: status_code= 403 message= "Your account doesn't have permissions to go so far!" except `Conflict` as e: status_code= 409 message= "Other user is working in the same information, he got there first" .... else: status_code= 201 message= "Object created with success!"
Different codes may be required depending on the exceptions you have identified. Go to Wikipedia and check the list. Do not forget that the answer is also different in code. If you add something to the database, you must return 201 . If you just received the information, you were looking for a GET request.
Answering questions
Django exceptions will return 500 errors if they are not handled, because if you do not know that an exception will occur, then this is an error on the server. With the exception of 404 and entry requirements, I would have made try catch blocks for everything. (For 404, you can raise it, and if you do @login_required or the permission that is required, django will respond with the appropriate code without doing anything).
I do not fully agree with this approach. As you said, the errors must be explicit, so you should always know what should happen, and how to explain it, and make it dependent on the operation being performed.
I would say 400 error for this. This is a bad request, you just need to explain why the error code for you and for your js code is so easily matched.
(example provided). In text_view you should have test_method , as in the third example.
The testing method should have the following structure:
def test_method(validated_data): try: my_business_logic_is_violated(): catch BusinessLogicViolation: raise else: ...
In my example:
try: test_method(form.cleaned_data) except `BusinessLogicViolation` as e: status_code= 400 message= "You violated the business logic" explanation = e.explanation ...
I considered the violation of business logic to be a clientβs mistake, because if something is necessary before this request, the client should know about it and ask the user to do this first. (From Error Definition ):
Status code 400 (invalid request) indicates that the server cannot or will not process the request due to what is perceived as a client error (for example, invalid request syntax, invalid request
creating messages or misleading request routing).
By the way, see Python Docs on Custom Exceptions , so you can give relevant error messages. The idea behind this example is that you throw a BusinessLogicViolation exception with another message in my_business_logic_is_violated() according to where it was generated.