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

将用户主键改为UUID后出现bigint与uuid不匹配的Django报错求助

解决将用户表主键改为UUID后出现的类型不匹配问题

1. 修复django_admin_log的user_id类型冲突

内置的django_admin_log表中user_id字段默认是bigint类型,和你的UUID主键不兼容,提供两种解决方案:

方案一:直接修改数据库字段(适合已上线项目)

  • 如果你用PostgreSQL,执行SQL修改字段类型:
ALTER TABLE django_admin_log ALTER COLUMN user_id TYPE uuid USING user_id::uuid;
  • 如果你用MySQL,改成CHAR(36)(MySQL无原生UUID类型):
ALTER TABLE django_admin_log MODIFY COLUMN user_id CHAR(36) NULL;

注意:操作前务必备份数据库,若原有django_admin_log中有旧数据,要确认数据转换的兼容性,必要时可清空日志表。

方案二:自定义AdminLog模型(适合新项目或可重构场景)

  • 在你的业务app中创建自定义日志模型:
from django.contrib.admin.models import LogEntryManager, DELETION
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import gettext_lazy as _
from your_app.models import User  # 替换成你的用户模型

class CustomAdminLog(models.Model):
    action_time = models.DateTimeField(_('action time'), auto_now_add=True)
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        verbose_name=_('user'),
        null=True,
    )
    content_type = models.ForeignKey(
        ContentType,
        on_delete=models.SET_NULL,
        verbose_name=_('content type'),
        null=True,
        blank=True,
    )
    object_id = models.TextField(_('object id'), blank=True, null=True)
    object_repr = models.CharField(_('object repr'), max_length=200)
    action_flag = models.PositiveSmallIntegerField(_('action flag'))
    change_message = models.TextField(_('change message'), blank=True)

    objects = LogEntryManager()

    class Meta:
        verbose_name = _('log entry')
        verbose_name_plural = _('log entries')
        ordering = ('-action_time',)

    def __str__(self):
        return f"{self.user} {self.get_action_flag_display()} {self.object_repr}"

    def is_addition(self):
        return self.action_flag == LogEntryManager.ADDITION

    def is_change(self):
        return self.action_flag == LogEntryManager.CHANGE

    def is_deletion(self):
        return self.action_flag == DELETION
  • 在settings.py中配置替换默认模型:
ADMIN_LOG_ENTRY_MODEL = 'your_app.CustomAdminLog'
  • 生成并执行迁移:
python manage.py makemigrations
python manage.py migrate

2. 适配oauth2_provider的Token模型

oauth2_provider默认的AccessToken和RefreshToken表中user_id也是bigint,同样需要适配:

方案一:直接修改数据库字段

  • PostgreSQL执行:
ALTER TABLE oauth2_provider_accesstoken ALTER COLUMN user_id TYPE uuid USING user_id::uuid;
ALTER TABLE oauth2_provider_refreshtoken ALTER COLUMN user_id TYPE uuid USING user_id::uuid;
  • MySQL执行:
ALTER TABLE oauth2_provider_accesstoken MODIFY COLUMN user_id CHAR(36) NULL;
ALTER TABLE oauth2_provider_refreshtoken MODIFY COLUMN user_id CHAR(36) NULL;

方案二:自定义Token模型

  • 在业务app中创建自定义模型:
from oauth2_provider.models import AbstractAccessToken, AbstractRefreshToken
from django.db import models
from your_app.models import User

class CustomAccessToken(AbstractAccessToken):
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        related_name="oauth2_access_tokens"
    )

class CustomRefreshToken(AbstractRefreshToken):
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        related_name="oauth2_refresh_tokens"
    )
  • 在settings.py中配置:
OAUTH2_PROVIDER = {
    'ACCESS_TOKEN_MODEL': 'your_app.CustomAccessToken',
    'REFRESH_TOKEN_MODEL': 'your_app.CustomRefreshToken',
}
  • 生成并执行迁移:
python manage.py makemigrations
python manage.py migrate

3. 确保/login和/register API正常工作

  • 检查用户模型,确保UUID主键自动生成:
import uuid
from django.db import models

class User(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # 其他字段...
  • 验证登录注册视图逻辑,确保创建用户时主键正确生成,OAuth2认证环节用UUID格式查询用户,避免类型转换错误。
  • 测试接口,确认返回的Token中关联的user_id是UUID格式,无类型匹配报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:35:29