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

在Django REST Framework及管理面板中将邮箱设为主键的问题

Hey there! Let's break down and solve your two Django/DRF problems step by step:

问题1:将邮箱作为用户模型的主键

Django自带的auth.User模型默认用自增id作为主键,要改成用邮箱作为主键,你需要自定义用户模型——因为默认的User模型是不能直接修改主键字段的。这里是具体实现步骤:

1. 定义自定义用户模型和管理器

在你的app的models.py中添加以下代码:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin

# 自定义用户管理器,处理用户创建逻辑
class CustomUserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError("Email is a required field!")
        # 标准化邮箱格式(比如转小写)
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        # 超级用户必须拥有staff和superuser权限
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)

        if extra_fields.get("is_staff") is not True:
            raise ValueError("Superuser must have is_staff=True")
        if extra_fields.get("is_superuser") is not True:
            raise ValueError("Superuser must have is_superuser=True")

        return self.create_user(email, password, **extra_fields)

# 自定义用户模型,用email作为主键
class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True, primary_key=True)  # 设置为主键
    first_name = models.CharField(max_length=50, blank=True)
    last_name = models.CharField(max_length=50, blank=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = CustomUserManager()

    # 指定登录时用邮箱作为标识
    USERNAME_FIELD = "email"
    # 创建超级用户时不需要额外必填字段(email已经是USERNAME_FIELD)
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

2. 配置Django使用自定义用户模型

在项目根目录的settings.py中添加一行,告诉Django使用你的自定义模型:

AUTH_USER_MODEL = "your_app_name.CustomUser"  # 替换成你的app名称

重要提醒

如果你的项目已经有过数据库迁移(比如执行过makemigrations或migrate),最好重置数据库(备份数据后):

  • 删除所有app下migrations文件夹里除了__init__.py的文件
  • 删除数据库文件(比如sqlite的db.sqlite3)
  • 重新执行python manage.py makemigrations和python manage.py migrate

问题2:解决管理站点的外键约束错误

这个1452错误的核心意思是:你创建ResearchProject时,指定的lead_researcher_id在关联的用户表中找不到对应的记录,导致外键约束失败。下面是常见原因和解决方法:

原因1:外键关联了错误的用户模型

如果你已经自定义了用户模型,但ResearchProject的外键还是指向默认的auth.User,就会出现这个问题。修改你的项目模型:

from django.db import models
from django.conf import settings

class ResearchProject(models.Model):
    lead_researcher = models.ForeignKey(
        settings.AUTH_USER_MODEL,  # 动态关联当前配置的用户模型
        on_delete=models.CASCADE,
        related_name="research_projects"
    )
    # 其他字段...

原因2:管理站点配置问题

检查你的admin.py,确保lead_researcher字段是可选择的下拉框,并且显示的是存在的用户:

from django.contrib import admin
from .models import ResearchProject

class ResearchProjectAdmin(admin.ModelAdmin):
    # 确保lead_researcher在列表和表单中正常显示
    list_display = ("project_name", "lead_researcher")
    fields = ("project_name", "lead_researcher", ...)  # 包含lead_researcher字段

admin.site.register(ResearchProject, ResearchProjectAdmin)

原因3:数据库存在脏数据

如果数据库里已有ResearchProject记录,它们的lead_researcher_id可能指向了已删除的用户。可以通过Django Shell修复:

  1. 打开Shell:python manage.py shell
  2. 执行以下代码清理无效记录:
from django.conf import settings
from your_app_name.models import ResearchProject

# 获取所有lead_researcher不存在的项目
invalid_projects = ResearchProject.objects.filter(
    lead_researcher__isnull=False
).exclude(
    lead_researcher__in=settings.AUTH_USER_MODEL.objects.all()
)

# 可以选择删除这些无效项目,或者重新分配给存在的用户
invalid_projects.delete()

原因4:迁移未正确执行

如果刚修改了用户模型或外键关联,确保重新执行迁移:

python manage.py makemigrations
python manage.py migrate

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:01:24