Django rest framwork - how to prevent 1062, "Duplicate entry"
at my Django application (DRF only), I'm trying to create a new object where one of the fields is setup like this:
resource_name = models.CharField(verbose_name="Resource Name", blank=False, null=False, max_length=50, unique=True)
If I now try to create an Object with the same resource_name twice, I'm always running into the following exception:
django.db.utils.IntegrityError: (1062, "Duplicate entry 'test_ressource123' for key 'resource_name'")
Is there any good solution that I can apply to all kinds of these situations? Would be awesome to simply make the API response that the object already exists, kinda strange that this is not already a built-in of DRF. Can I maybe overwrite the def create function call of the serializer ? Any good advice welcome.
2 answers
-
answered 2022-01-20 00:37
Yevgeniy Kosmak
Generally, you should develop a serializer for each model to understand how you work with each one. Later you can forget about this "common" solution and look for a bug for a long time.
Nevertheless, I see two approaches to achieve that behavior.
Overriden
ModelViewSet
We can redefine the
create
method of defaultModelViewSet
and then inherit yourModelViewSet
s from this class. Like this:from django.db import IntegrityError from rest_framework import viewsets from rest_framework.exceptions import APIException from rest_framework.status import HTTP_400_BAD_REQUEST class SupressIntegrityErrorModelViewSet(viewsets.ModelViewSet): def create(self, request, *args, **kwargs): try: return super().create(request, *args, **kwargs) except IntegrityError as e: raise APIException(detail=str(e), code=HTTP_400_BAD_REQUEST)
More information here.
DRF custom exception handling
Firstly you need to make a
custom_exception_handler
method; DRF documentation suggests making it in<application-directory>/utils.py
:from django.http import HttpResponseBadRequest from rest_framework.views import exception_handler def custom_exception_handler(exc, context): if type(exc).__name__ == 'IntegrityError': return HttpResponseBadRequest(str(e)) return exception_handler(exc, context)
Then you have to set
EXCEPTION_HANDLER
in yoursettings.py
:REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler' }
-
answered 2022-02-25 18:03
Mohammad sadegh borouny
It is better to add
UniqueValidator
to your serializer.resource_name = serializers.CharField(max_length=50, validators=[UniqueValidator(queryset=YourModel.objects.all())], requierd=False)
do you know?
how many words do you know