Getting an error when adding multiple values to a ManyToMany field

Here is my models.py:

from django.db import models


# Create your models here.
class Term(models.Model):
    name = models.CharField(max_length=100)
    definition = models.TextField()
    depends_on = models.ManyToManyField('self', symmetrical=False, blank=True, through='TermDependency')
    modules = models.ManyToManyField('Module', symmetrical=True, blank=True)

    def __str__(self):
        return self.name


class TermDependency(models.Model):
    parent_term = models.ForeignKey(Term, related_name='parent_term', on_delete=models.CASCADE)
    child_term = models.ForeignKey(Term, related_name='child_term', on_delete=models.CASCADE)


class Module(models.Model):
    name = models.CharField(max_length=100)
    depends_on = models.ManyToManyField('self', symmetrical=False, blank=True, through='ModuleDependency')
    terms = models.ManyToManyField(Term, symmetrical=True, blank=True)

    def __str__(self):
        return self.name


class ModuleDependency(models.Model):
    parent_module = models.ForeignKey(Module, related_name='parent_module', on_delete=models.CASCADE)
    child_module = models.ForeignKey(Module, related_name='child_module', on_delete=models.CASCADE)


class ModuleTerm(models.Model):
    module = models.ForeignKey(Module, related_name='module_with_term', on_delete=models.CASCADE)
    term = models.ForeignKey(Term, related_name='term_with_module', on_delete=models.CASCADE)

I get my error from submitting this:

The error I get is this:

Internal Server Error: /admin/modules/module/add/
Traceback (most recent call last):
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\db\backends\base\base.py", line 299, in _commit
    return self.connection.commit()
           ^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.IntegrityError: FOREIGN KEY constraint failed

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\contrib\admin\options.py", line 714, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\utils\decorators.py", line 188, in _view_wrapper
    result = _process_exception(request, e)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\utils\decorators.py", line 186, in _view_wrapper
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\views\decorators\cache.py", line 80, in _view_wrapper
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\contrib\admin\sites.py", line 240, in inner
    return view(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\contrib\admin\options.py", line 1941, in add_view
    return self.changeform_view(request, None, form_url, extra_context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\utils\decorators.py", line 48, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\utils\decorators.py", line 188, in _view_wrapper
    result = _process_exception(request, e)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\utils\decorators.py", line 186, in _view_wrapper
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\contrib\admin\options.py", line 1801, in changeform_view
    with transaction.atomic(using=router.db_for_write(self.model)):
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\db\transaction.py", line 263, in __exit__
    connection.commit()
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\db\backends\base\base.py", line 323, in commit
    self._commit()
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\db\backends\base\base.py", line 298, in _commit
    with debug_transaction(self, "COMMIT"), self.wrap_database_errors:
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\db\utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "A:\PythonProjects\learn-math-api\venv\Lib\site-packages\django\db\backends\base\base.py", line 299, in _commit
    return self.connection.commit()
           ^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
[18/Dec/2023 16:56:39] "POST /admin/modules/module/add/ HTTP/1.1" 500 149805
[18/Dec/2023 17:21:28] "GET /admin/modules/module/add/ HTTP/1.1" 200 10298

You’ve got duplicate ManyToManyField definitions in Module and Term. You should only specify the field in one of the two models involved. (I don’t know if that is going to cause this specific issue, but it is a problem.)

What duplicate fields do I have? I thought I could have fields with the same names as long I had them in different models.

You have:

and

This is two identical definitions for the same relationship between those two models.

You only define a ManyToManyField on one side of the many-to-many relationship.

Review the docs at Model field reference | Django documentation | Django and Related objects reference | Django documentation | Django

Thank you. I’m still trying to figure out what this ForeignKey error is because I’ve never seen this before on many-to-many relationships.

At a minimum, start by fixing your models. Let’s at least remove that as a possible cause.

Then, post your ModelAdmin class for Module.

This is what I have now:

from django.db import models


# Create your models here.
class Term(models.Model):
    name = models.CharField(max_length=100)
    definition = models.TextField()
    depends_on = models.ManyToManyField('self', symmetrical=False, blank=True, through='TermDependency')

    def __str__(self):
        return self.name


class TermDependency(models.Model):
    parent_term = models.ForeignKey(Term, related_name='parent_term', on_delete=models.CASCADE)
    child_term = models.ForeignKey(Term, related_name='child_term', on_delete=models.CASCADE)


class Module(models.Model):
    name = models.CharField(max_length=100)
    depends_on = models.ManyToManyField('self', symmetrical=False, blank=True, through='ModuleDependency')
    terms = models.ManyToManyField(Term, symmetrical=True, blank=True)

    def __str__(self):
        return self.name


class ModuleDependency(models.Model):
    parent_module = models.ForeignKey(Module, related_name='parent_module', on_delete=models.CASCADE)
    child_module = models.ForeignKey(Module, related_name='child_module', on_delete=models.CASCADE)


class ModuleTerm(models.Model):
    module = models.ForeignKey(Module, related_name='module_with_term', on_delete=models.CASCADE)
    term = models.ForeignKey(Term, related_name='term_with_module', on_delete=models.CASCADE)

This is my admin.py:

from django.contrib import admin

from modules.models import Term, Module


# Register your models here.
@admin.register(Term)
class TermAdmin(admin.ModelAdmin):
    pass

@admin.register(Module)
class ModuleAdmin(admin.ModelAdmin):
    pass

I’m just using default fields.

And you’ve done a makemigrations / migrate, and you’re still getting the exact same error as before?

I just rebuilt my makemigrations / migrate and reset the database and I still get the same error. Btw I’m using sqlite3 for my DB.

What version of Python and Django are you using?

I’m using Python 3.12 and Django 5.0

Ack - scratch this. I forgot - symmetrical is only used for ManyToMany for self. Remove it from your ManyToManyField definition. See ManyToManyField.symmetrical

Thank you very much. This fixed the error.