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
相关产品推荐
相关产品推荐

