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

Django自定义User模型遇反向访问器冲突问题求助

解决Django自定义User模型反向访问器冲突问题

问题描述

系统检查时出现以下冲突错误:

错误信息:
auth.User.groups: (fields.E304) 'auth.User.groups'的反向访问器'Group.user_set'与'user.User.groups'的反向访问器冲突。
        提示:为'auth.User.groups'或'user.User.groups'的定义添加或修改related_name参数。
auth.User.user_permissions: (fields.E304) 'auth.User.user_permissions'的反向访问器'Permission.user_set'与'user.User.user_permissions'的反向访问器冲突。
        提示:为'auth.User.user_permissions'或'user.User.user_permissions'的定义添加或修改related_name参数。
user.User.groups: (fields.E304) 'user.User.groups'的反向访问器'Group.user_set'与'auth.User.groups'的反向访问器冲突。
        提示:为'user.User.groups'或'auth.User.groups'的定义添加或修改related_name参数。
user.User.user_permissions: (fields.E304) 'user.User.user_permissions'的反向访问器'Permission.user_set'与'auth.User.user_permissions'的反向访问器冲突。
        提示:为'user.User.user_permissions'或'auth.User.user_permissions'的定义添加或修改related_name参数。

自定义User模型代码:

class User(AbstractUser):
    name = models.CharField(max_length=50, verbose_name=_('name'))
    profile = models.ImageField(upload_to='images/profile/', verbose_name=_('profile'))
    phone = models.CharField(
        _('Phone'),
        max_length=11,
        unique=True,
    )

    USERNAME_FIELD = 'phone'
    REQUIRED_FIELDS = []
    objects = UserManager()
    username = None

    class Meta:
        app_label = 'user'
        verbose_name = _("user")
        verbose_name_plural = _(" users")

    def __str__(self) -> str:
        return str(self.phone)

解决方案

冲突原因是自定义User模型继承了AbstractUser,而Django自带的auth.User模型同样拥有groups和user_permissions字段,两者的反向访问器默认名称都是user_set,导致命名冲突。以下两种方法可解决:

方法一:覆盖字段并指定唯一related_name

在自定义User模型中重新定义groups和user_permissions字段,给它们设置不重复的反向访问器名称:

from django.contrib.auth.models import AbstractUser, Group, Permission
from django.db import models
from django.utils.translation import gettext_lazy as _

class User(AbstractUser):
    name = models.CharField(max_length=50, verbose_name=_('name'))
    profile = models.ImageField(upload_to='images/profile/', verbose_name=_('profile'))
    phone = models.CharField(
        _('Phone'),
        max_length=11,
        unique=True,
    )
    
    # 覆盖groups字段,指定唯一反向访问器
    groups = models.ManyToManyField(
        Group,
        verbose_name=_('groups'),
        blank=True,
        related_name='custom_user_groups',
        related_query_name='custom_user',
    )
    # 覆盖user_permissions字段,指定唯一反向访问器
    user_permissions = models.ManyToManyField(
        Permission,
        verbose_name=_('user permissions'),
        blank=True,
        related_name='custom_user_permissions',
        related_query_name='custom_user',
    )

    USERNAME_FIELD = 'phone'
    REQUIRED_FIELDS = []
    objects = UserManager()
    username = None

    class Meta:
        app_label = 'user'
        verbose_name = _("user")
        verbose_name_plural = _("users")

    def __str__(self) -> str:
        return str(self.phone)

方法二:配置AUTH_USER_MODEL(推荐)

如果项目从一开始就计划使用自定义User模型,直接在项目的settings.py中添加以下配置,让Django默认使用你的自定义模型,彻底避免冲突:

# settings.py
AUTH_USER_MODEL = 'user.User'

注意:该配置必须在项目初始化阶段设置,若已生成迁移文件或创建了数据库表,需先清理旧迁移和数据,再配置该参数,否则会引发其他数据库迁移问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 08:29:54