首页 > 解决方案 > 如何解决“模型用作中间模型但它没有模型的外键”?

问题描述

错误信息:

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'.

我试图在权限模型下将外键添加到“类别”,但仍然出现相同的错误。

模型.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

我正在尝试使用“通过”参数来包含 MobileApp 和类别的权限 m2m 的描述字段

标签: pythondjango

解决方案


这是各种破碎。

显然你希望你的多对多在 Category 和 MobileApp 之间,通过模型作为 Permission。所以 m2m 字段需要声明:

class Category(models.Model):
    name = models.CharField(max_length=50)
    permission = models.ManyToManyField('MobileApp',
                                        related_name='category_permissions',
                                        through='Permission'
                                        )

其次,正如错误所述,在直通模型中,双方都需要外键。另外,您需要为他们提供合理的名称和相关名称。所以:

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')

最后,您不需要在 PermissionCategory的另一个方向上定义 m2ms 。从 MobileApp 中删除category和字段。permission


推荐阅读