I am currently making a simple CRUD
application on Django Rest Framework
.
I need to return a response to the client for any request in a specific structure.
For example, if a client makes a POST
request to create a new record and it was executed successfully, then API needs to return such structure:
{
"data": [
{
"id": 1,
"email": "[email protected]",
}
],
"error": {}
}
Let's say the problem is related to the model field. In this case, the API should return such a structure:
{
"data": [],
"error": {
"email": [
"This field is required."
]
}
}
If the problem is not related to the model field, then it is necessary to return to the client such a structure where there would be a description of the error:
{
"data": [],
"error": {
"non_field_errors": [
"Description of the error."
]
}
}
Depending on the error, I also have to return different statuses in the query responses.
openapi-schema.js:
/clients:
post:
summary: Create New Client
operationId: post-clients
responses:
'200':
description: Client Created
content:
application/json:
schema:
$ref: '#/components/schemas/Result'
examples: {}
'400':
description: Missing Required Information
'409':
description: Email Already Taken
My current code returns an incorrect structure. Should I configure all this at the serialization level?
{
"data": [],
"error": {
"non_field_errors": [
"{'email': [ErrorDetail(string='person with this email already exists.', code='unique')]}"
]
}
}
models.py:
class Client(models.Model):
id = models.AutoField(primary_key=True)
email = models.EmailField(unique=True)
class Meta:
db_table = "clients"
def __str__(self):
return self.email
serializers.py:
class ClientSerializer(serializers.ModelSerializer):
class Meta:
model = Client
views.py:
class ClientView(APIView):
def post(self, request):
data = []
error = {}
result = {"data": data, "error": error}
try:
client_serializer = ClientSerializer(data=request.data)
client_serializer.is_valid(raise_exception=True)
client_serializer.save()
data.append(client_serializer.data)
return Response(result, status=status.HTTP_201_CREATED)
except Exception as err:
error['non_field_errors'] = [str(err)]
return Response(result, status=status.HTTP_200_OK)
CodePudding user response:
You can return response data as you want.
class ClientView(APIView):
def post(self, request):
data = []
error = {}
result = {"data": data, "error": error}
try:
client_serializer = ClientSerializer(data=request.data)
if not client_serializer.is_valid():
result["error"] = client_serializer.errors
return Response(result, status=status.HTTP_400_BAD_REQUEST)
client_serializer.save()
data.append(client_serializer.data)
result["data"] = data
return Response(result, status=status.HTTP_201_CREATED)
except Exception as err:
result["data"] = []
result["error"] = "Something went wrong"
return Response(result, status=status.HTTP_200_OK)
CodePudding user response:
it depends your side
{
"data": [],
"error": {
"email": [
"This field is required."
]
}
}
I have to say this sometimes wrong because errors could be different, I mean, there could be string validations, country based checking or others.
I suggest this code
{
"data": [],
"error": {
"non_field_errors": [
{'email': [ErrorDetail(string='person with this email already exists.', code='unique')]}
]
}
}
another case you can get errors and manually send them to client side, like:
client_serializer = ClientSerializer(data=request.data)
if client_serializer.is_valid():
return client_serializer.save()
else:
return {"errors": client_serializer.errors}