skip to Main Content

I have two apps Levels, Classes with Many To Many Relationships, Levels can have many Classes, and Classes can have many Levels.

I want classes and levels use the same table.

How can I do that?

I tried:

levels/models.py

class Level(models.Model):
    name = models.CharField(max_length=50)
    classes = models.ManyToManyField(ChildClass, related_name='childclass', blank=True,db_table='level_class', primary_key=False)

child_class/models.py

class ChildClass(models.Model):
    name = models.CharField(max_length=50)
    levels = models.ManyToManyField('level.Level', related_name='childclass',db_table='level_class')

Returns (Error)

child_class.ChildClass.levels: (fields.E340) The field’s intermediary table ‘level_class’ clashes with the table name of ‘level.Level.classes’.
level.Level.classes: (fields.E340) The field’s intermediary table ‘level_class’ clashes with the table name of ‘child_class.ChildClass.levels’.

2

Answers


  1. According to the Django documentation, https://docs.djangoproject.com/en/4.2/topics/db/models/, under many to many relationship you can create an intermediary model to Foreign key both the Level and Class models to hold the fields that are common and govern both the models. Also the many to many relationship can only be defined on one model not both and it is recommended you put the relationship on a model that brings sense.
    
    class Level(models.Model):
        name = models.CharField(max_length=128
    
    
    class ChildClass(models.Model):
        name = models.CharField(max_length=128)
        members = models.ManyToManyField(Level, through="Intermediate")
    
    
    class Intermediate(models.Model):
        Level= models.ForeignKey(Level, on_delete=models.CASCADE)
        ChildClass= models.ForeignKey(ChildClass, on_delete=models.CASCADE)
        
    
    Login or Signup to reply.
  2. You are getting this error because you have defined two ManyToManyField relationships in two different models (Level and ChildClass), and you are trying to use the same intermediary table ‘level_class’ for both relationships.

    In a many-to-many relationship, you should only define the relationship on one side, and the other side can access it via the related_name attribute.

    In your case, you can remove the ManyToManyField from the ChildClass model, and only keep it in the Level model.

    Try this:

    #levels/models.py
    
    from django.db import models
    from child_class.models import ChildClass
    
    class Level(models.Model):
        name = models.CharField(max_length=50)
        classes = models.ManyToManyField(ChildClass, related_name='levels', blank=True)
    
    #child_class/models.py
    from django.db import models
    
    class ChildClass(models.Model):
        name = models.CharField(max_length=50)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search