Django - overriding save method with super returns unique contraint error when creating object

Overriding save method with super returns unique contraint error when creating object. How to solve it?

def save(self, *args, **kwargs):
        if self.pk is None:
            super(IntoDocumentProduct, self).save(*args, **kwargs)
            # some logic
        # more logic
        super(IntoDocumentProduct, self).save(*args, **kwargs)
        self.full_clean()

Below is the error that appears in the console. It directs specifically to the save() method in the model. I don't know what is wrong with it. After all, I can't use self.save(), because there will be a recursive loop.

Traceback (most recent call last):
  File "W:\projects\foodgast\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\views\generic\base.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "W:\projects\foodgast\venv\Lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "W:\projects\foodgast\venv\Lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Sebastian\AppData\Local\Programs\Python\Python311\Lib\contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\src\wms\api\views.py", line 183, in post
    serializer.save()
  File "W:\projects\foodgast\venv\Lib\site-packages\rest_framework\serializers.py", line 212, in save
    self.instance = self.create(validated_data)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\rest_framework\serializers.py", line 962, in create
    instance = ModelClass._default_manager.create(**validated_data)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\models\query.py", line 671, in create
    obj.save(force_insert=True, using=self.db)
  File "W:\projects\foodgast\src\wms\models.py", line 621, in save
    super(IntoDocumentProduct, self).save(*args, **kwargs)
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\models\base.py", line 812, in save
    self.save_base(
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\models\base.py", line 863, in save_base
    updated = self._save_table(
              ^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\models\base.py", line 1006, in _save_table
    results = self._do_insert(
              ^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\models\base.py", line 1047, in _do_insert
    return manager._insert(
           ^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\models\query.py", line 1791, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\models\sql\compiler.py", line 1660, in execute_sql
    cursor.execute(sql, params)
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\backends\utils.py", line 103, in execute
    return super().execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\backends\utils.py", line 67, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\backends\utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "W:\projects\foodgast\venv\Lib\site-packages\django\db\backends\utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.IntegrityError: duplicate key value violates unique constraint "wms_dokumentprzyjeciaprodukt_pkey"
DETAIL:  Key (id)=(150) already exists.

I am also posting the error that shows up when I test the api in insomnia.

IntegrityError at /api/wms/intodocuments/products/create/
duplicate key value violates unique constraint "wms_dokumentprzyjeciaprodukt_pkey"
DETAIL:  Key (id)=(151) already exists.

I'm like 90% sure you have to define your super properly. I tried what you have and didn't get a compile error, but it's definitely not best practices. Particularly, if you're not defining a return within your if statement. That would cause super to be called twice which could be throwing the exception due to the save function running twice. I typically set it right after my function declaration (my prefered method) or as my last line.

def save(self, *args, **kwargs):
   super(IntoDocumentProduct, self).save(*args, **kwargs)
   # your overwrite code

or

def save(self, *args, **kwargs):
    # your overwrite code
    super(IntoDocumentProduct, self).save(*args, **kwargs)
Back to Top