How to fix "the model is used as in intermediate model but it does not have foreign key to a model"?
Question:
Error Message:
blogs.Permission: (fields.E336) The model is used as an intermediate model by 'blogs.Category.permission', but it does not have a foreign key to 'Category' or 'Permission'.
I have tried to add a Foreign Key to ‘Category’ under Permission model, same error still occurs.
models.py:
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=50)
permission = models.ManyToManyField('Permission',
related_name='category_permissions',
through='Permission'
)
def __str__(self):
return self.name
class Permission(models.Model):
HIGH = 'High'
MEDIUM = 'Medium'
LOW = 'Low'
CLASSIFICATION_CHOICES = [
(HIGH, 'High'),
(MEDIUM, 'Medium'),
(LOW, 'Low')
]
category_name = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category_name')
name = models.CharField(max_length=100)
description = models.TextField()
platform = models.CharField(
max_length=10,
choices=PLATFORM_CHOICES,
default=BOTH,
)
classification = models.CharField(
max_length=10,
choices=CLASSIFICATION_CHOICES,
default=LOW,
)
def __str__(self):
return self.name
class MobileApp(models.Model):
name = models.CharField(max_length=200)
icon = models.ImageField(upload_to='app_icons', blank=True, null=True)
platform = models.CharField(
max_length=10,
choices=PLATFORM_CHOICES,
default=IOS,
)
category = models.ManyToManyField('Category')
provider = models.CharField(max_length=200)
identifier = models.CharField(max_length=200)
permission = models.ManyToManyField(Permission,
related_name='mobile_app_permission',
)
def __str__(self):
return self.name
I am trying to use ‘through’ argument to include the description field of the permission m2m for MobileApp and Category
Answers:
This is all kinds of broken.
Apparently you want your many-to-many to be between Category and MobileApp, with the through model as Permission. So the m2m field needs to declare that:
class Category(models.Model):
name = models.CharField(max_length=50)
permission = models.ManyToManyField('MobileApp',
related_name='category_permissions',
through='Permission'
)
Secondly, as the error states, in the through model you need foreign keys to both sides. Plus, you need to give them sensible names and related_names. So:
class Permission(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='permissions')
mobile_app = models.ForeignKey('MobileApp', on_delete=models.CASCADE, related_name='permissions')
Finally, you don’t need to also define m2ms in the other direction to either Permission or Category. Remove the category
and permission
fields from MobileApp.
I had the same prolem but i forgot that the ManyToManyField needs to use two different models in the class parameters "class=" and "through=" look at my code:
User is another class model which is declared somewhere else.
class Teams(models.Model):
owner = models.ForeignKey(User, related_name="teams_owner", on_delete=models.CASCADE, primary_key=True)
operators = models.ManyToManyField(User, related_name="teams_opearators", through="Operator")
class Operator(models.Model):
team = models.ForeignKey(Teams, related_name="team", on_delete=models.CASCADE)
operator = models.ForeignKey(User, on_delete=models.CASCADE, related_name="operator")
active = models.BooleanField(default=False)
it’s wrong to use the code like this:
class Teams(models.Model):
owner = models.ForeignKey(User, related_name="teams_owner", on_delete=models.CASCADE, primary_key=True)
operators = models.ManyToManyField(Operator, related_name="teams_opearators", through="Operator")
Error Message:
blogs.Permission: (fields.E336) The model is used as an intermediate model by 'blogs.Category.permission', but it does not have a foreign key to 'Category' or 'Permission'.
I have tried to add a Foreign Key to ‘Category’ under Permission model, same error still occurs.
models.py:
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=50)
permission = models.ManyToManyField('Permission',
related_name='category_permissions',
through='Permission'
)
def __str__(self):
return self.name
class Permission(models.Model):
HIGH = 'High'
MEDIUM = 'Medium'
LOW = 'Low'
CLASSIFICATION_CHOICES = [
(HIGH, 'High'),
(MEDIUM, 'Medium'),
(LOW, 'Low')
]
category_name = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category_name')
name = models.CharField(max_length=100)
description = models.TextField()
platform = models.CharField(
max_length=10,
choices=PLATFORM_CHOICES,
default=BOTH,
)
classification = models.CharField(
max_length=10,
choices=CLASSIFICATION_CHOICES,
default=LOW,
)
def __str__(self):
return self.name
class MobileApp(models.Model):
name = models.CharField(max_length=200)
icon = models.ImageField(upload_to='app_icons', blank=True, null=True)
platform = models.CharField(
max_length=10,
choices=PLATFORM_CHOICES,
default=IOS,
)
category = models.ManyToManyField('Category')
provider = models.CharField(max_length=200)
identifier = models.CharField(max_length=200)
permission = models.ManyToManyField(Permission,
related_name='mobile_app_permission',
)
def __str__(self):
return self.name
I am trying to use ‘through’ argument to include the description field of the permission m2m for MobileApp and Category
This is all kinds of broken.
Apparently you want your many-to-many to be between Category and MobileApp, with the through model as Permission. So the m2m field needs to declare that:
class Category(models.Model):
name = models.CharField(max_length=50)
permission = models.ManyToManyField('MobileApp',
related_name='category_permissions',
through='Permission'
)
Secondly, as the error states, in the through model you need foreign keys to both sides. Plus, you need to give them sensible names and related_names. So:
class Permission(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='permissions')
mobile_app = models.ForeignKey('MobileApp', on_delete=models.CASCADE, related_name='permissions')
Finally, you don’t need to also define m2ms in the other direction to either Permission or Category. Remove the category
and permission
fields from MobileApp.
I had the same prolem but i forgot that the ManyToManyField needs to use two different models in the class parameters "class=" and "through=" look at my code:
User is another class model which is declared somewhere else.
class Teams(models.Model):
owner = models.ForeignKey(User, related_name="teams_owner", on_delete=models.CASCADE, primary_key=True)
operators = models.ManyToManyField(User, related_name="teams_opearators", through="Operator")
class Operator(models.Model):
team = models.ForeignKey(Teams, related_name="team", on_delete=models.CASCADE)
operator = models.ForeignKey(User, on_delete=models.CASCADE, related_name="operator")
active = models.BooleanField(default=False)
it’s wrong to use the code like this:
class Teams(models.Model):
owner = models.ForeignKey(User, related_name="teams_owner", on_delete=models.CASCADE, primary_key=True)
operators = models.ManyToManyField(Operator, related_name="teams_opearators", through="Operator")