Django Product模型如何设置slug拼接UUID的自定义主键id
解决方案
你需要将原有的UUIDField类型的id改为CharField,并通过重写模型save方法实现slug与短UUID的拼接逻辑,修改后的完整配置如下:
步骤1:调整字段定义
import uuid from django.db import models from django.utils.text import slugify class Product(models.Model): # 替换原UUIDField为CharField,长度预留足够的拼接空间 id = models.CharField(primary_key=True, max_length=260, editable=False) # 原有slug字段保留即可 slug = models.SlugField(max_length=250, unique_for_date='published') # 你的其他字段,比如商品名称name、发布时间published等 name = models.CharField(max_length=200) published = models.DateTimeField(auto_now_add=True)
注意max_length需要设置为
slug的max_length + 9以上:1位连接横杠 + 至少8位UUID的长度,避免字符串溢出报错。如果需要更长的UUID降低碰撞概率,对应调大max_length即可。
步骤2:重写save方法实现拼接逻辑
在Product模型内添加save方法,首次保存时自动拼接生成id:
def save(self, *args, **kwargs): # 仅首次保存未生成id时执行拼接逻辑 if not self.id: # 如果你没有提前处理slug,这里可以自动从商品名称生成slug if not self.slug: self.slug = slugify(self.name) # 取uuid4的前8位十六进制字符串,可根据需要调整截取长度 short_uuid = uuid.uuid4().hex[:8] self.id = f"{self.slug}-{short_uuid}" super().save(*args, **kwargs)
注意事项
- 拼接后的id不符合UUID标准格式,所以必须使用
CharField存储,不能继续用UUIDField - UUID截取8位已经可以满足绝大多数场景的唯一性要求,如果你业务量极大,可以调整为截取12~16位降低碰撞概率
- 要保证拼接id之前slug已经被正确赋值,避免出现slug为空的无效id
内容的提问来源于stack exchange,提问作者some nooby questions
相关产品推荐
相关产品推荐

