You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django UniqueConstraint对模型及中间模型不生效,迁移检测无变更如何解决?

问题根源

你代码里的UniqueConstraint存在两处错误导致Django检测不到模型变更:

  1. 没有将UniqueConstraint放到Meta类的constraints列表属性中,只是作为无效语句写在Meta类内,Django不会识别这类游离的模型定义语句
  2. 约束字段错误使用了跨表关联语法__id,中间表的联合唯一约束直接使用外键字段名即可,不需要加后缀

修正方案

1. 修正RecipeTag模型的Meta定义

class RecipeTag(models.Model):
    """Intermediate "join" table for a relation between a recipe and tag.
    """
    recipe = models.ForeignKey(
        'Recipe',
        on_delete=models.CASCADE,
        verbose_name='рецепт',
    )

    tag = models.ForeignKey(
        'Tag',
        on_delete=models.CASCADE,
        verbose_name='тэг',
    )

    class Meta:
        verbose_name = 'отношение рецепта к тэгу'
        verbose_name_plural = 'отношение рецепта к тэгам'
        # 修正:将约束放入constraints列表,使用直接字段名
        constraints = [
            models.UniqueConstraint(
                fields=('recipe', 'tag'),
                name='recipe_tag_unique_constraint'
            )
        ]

    def __str__(self):
        return f'РецептТэг - id: {self.id}.'

2. 为RecipeIngredient也添加同样的联合唯一约束(避免重复食材)

class RecipeIngredient(models.Model):
    """Intermediate "join" table for a relation between a recipe
    and an ingredient. Additionaly implements <amount> field.
    """
    recipe = models.ForeignKey(
        'Recipe',
        on_delete=models.CASCADE,
        verbose_name='рецепт',
    )

    ingredient = models.ForeignKey(
        'Ingredient',
        on_delete=models.CASCADE,
        verbose_name='игредиент',
    )

    amount = models.IntegerField(
        default=1,
        validators=(
            MinValueValidator(1),
            MaxValueValidator(44640)
        ),
        verbose_name='количество',
    )

    class Meta:
        verbose_name = 'отношение рецепта к ингредиенту'
        verbose_name_plural = 'отношение рецепта к ингредиентам'
        # 新增食材联合唯一约束
        constraints = [
            models.UniqueConstraint(
                fields=('recipe', 'ingredient'),
                name='recipe_ingredient_unique_constraint'
            )
        ]

    def __str__(self):
        return f'РецептИнгредиент - id: {self.id}.'

3. 执行迁移

修正后重新执行迁移命令即可:

python manage.py makemigrations
python manage.py migrate

内容的提问来源于stack exchange,提问作者JohnShallow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 00:18:03