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

Django自定义Web3用户模型创建超级用户public_address唯一约束问题

问题解答

一、用户分离实现方式的合理性评估

该设计思路本身没有架构性问题,是可行的,但当前实现存在明显缺陷:

  • 你当前为超级用户生成299以内随机整数作为public_address的方案不可行:随机范围过小,最多只能生成299个不重复值,重复概率极高,这就是你触发UNIQUE约束报错的直接原因。同时真实Web3钱包地址是符合规范的十六进制字符串,随机整数存在和真实用户地址碰撞的风险。
  • 优化方案:为超级用户的public_address增加专属标识前缀,完全避免和真实钱包地址冲突,同时用足够长的随机串保证唯一性,示例:
    public_address = f"su_{secrets.token_hex(30)}"
    
  • 后续开发Web3认证后端时,可以直接在认证逻辑中判断public_address前缀,超级用户走用户名密码校验,普通用户走钱包签名校验即可,逻辑清晰无耦合。

二、断点不触发的原因及其他代码问题

1. 断点未触发核心原因

你贴出的Web3User模型代码中,没有显式指定自定义管理器,Django默认会使用父类AbstractUser自带的UserManager,完全不会走你写的Web3UserManager逻辑,所以断点永远不会触发。你需要在Web3User类中补充一行代码指定管理器:

class Web3User(AbstractUser):
    # 新增这行指定自定义管理器
    objects = Web3UserManager()
    public_address = models.CharField(max_length=64, unique=True)
    nonce = models.CharField(max_length=64)

也正因为程序走的是默认管理器,不会处理public_address字段,创建超级用户时该字段要么为空,要么重复,自然会持续触发UNIQUE约束报错。

2. 其他需要修复的代码错误

  • create_user方法参数设计错误:你当前create_user只接收public_address参数,但你在create_superuser调用时传入的username、password会被直接丢弃,同时你没有调用set_password方法对密码做哈希处理,就算创建了超级用户也无法正常登录。
    修改后的create_user示例:
def create_user(self, public_address, username=None, password=None, **extra_fields):
    if not public_address:
        raise ValueError('Users must have a public_address')
    extra_fields.setdefault('is_admin', False)
    user = self.model(
        public_address=public_address,
        nonce=secrets.token_urlsafe(32),
        username=username,
        **extra_fields
    )
    if password:
        user.set_password(password)
    user.save(using=self._db)
    return user
  • create_superuser需要补充默认字段校验:需要给is_staff、is_superuser设置为True,否则创建的用户没有管理员权限。
    修改后的create_superuser示例:
def create_superuser(self, username, password=None, **extra_fields):
    extra_fields.setdefault('is_admin', True)
    extra_fields.setdefault('is_staff', True)
    extra_fields.setdefault('is_superuser', True)
    # 生成不会和真实钱包地址冲突的唯一public_address
    public_address = f"su_{secrets.token_hex(30)}"
    return self.create_user(
        public_address=public_address,
        username=username,
        password=password,
        **extra_fields
    )

内容的提问来源于stack exchange,提问作者Kyle Calica-St

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:18:02