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

Django电商项目执行migrate报错:UNIQUE constraint failed: new__product_product.brand_id

解决方案:Django迁移时出现UNIQUE constraint failed: new__product_product.brand_id错误

错误原因

你将Product模型中的brand字段从CharField改为ForeignKey后,设置的默认值是字符串'Markon',但ForeignKey字段需要的是Brand模型实例的主键(通常是整数类型的id),而非品牌名称字符串。当执行迁移时,Django无法将字符串默认值映射到有效的Brand记录,进而触发唯一约束冲突。

解决步骤

1. 确保存在默认品牌记录

首先通过Django Shell创建或获取名为Markon的Brand实例:

python manage.py shell

在Shell中执行:

from product.models import Brand
# 自动创建(如果不存在)并获取Markon品牌,slug需满足唯一约束
brand, created = Brand.objects.get_or_create(name='Markon', slug='markon')

2. 修正Product模型的默认值设置

将brand字段的默认值改为可调用对象,确保返回有效Brand实例的主键:

def get_default_brand():
    # 确保每次调用都能获取到Markon品牌的id
    return Brand.objects.get_or_create(name='Markon', slug='markon')[0].id

class Product(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, on_delete=models.DO_NOTHING)
    main_image = models.ImageField(upload_to='product_images/%Y/%m/%d/')
    detail = models.TextField()
    keywords = models.CharField(max_length=50)
    description = models.CharField(max_length=1000)
    price = models.FloatField()
    # 替换原来的默认值设置
    brand = models.ForeignKey(Brand, on_delete=models.DO_NOTHING, default=get_default_brand)
    sale = models.IntegerField(blank=True, null=True, verbose_name="Sale (%)")
    bestseller = models.BooleanField(default=False)
    amount = models.IntegerField(blank=True, null=True)
    available = models.BooleanField(default=True)
    stock = models.BooleanField(default=True)
    date_created = models.DateTimeField(auto_now_add=True)
    used = models.BooleanField(default=False)
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)

3. 重新生成并执行迁移

  • 如果之前已经生成了错误的迁移文件,删除product/migrations/目录下除__init__.py之外的最新迁移文件。
  • 重新生成迁移:
python manage.py makemigrations
  • 执行迁移:
python manage.py migrate

额外注意事项

  • 若原有Product表中存在大量数据,迁移时Django会为所有旧数据的brand_id字段填充默认品牌的主键,确保默认品牌存在是关键。
  • 避免直接使用固定整数作为默认值(如default=1),因为不同环境中品牌的id可能不一致,使用可调用对象更具兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:45:32