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

Django自定义User模型报错:'User'对象无'user_type'属性

问题

我基于AbstractUser创建了自定义User模型,同时配套了Profile模型用于收集用户注册后的额外信息。注册时已经收集了「用户类型:雇主/雇员」,并且通过Admin后台确认数据已正确存入数据库,但在profile视图中访问user.user_type时,报错'User' object has no attribute 'user_type',错误出现在employer_profile_view函数的第112行。

相关代码

1. employer_profile_view.py

def employer_profile_view(request, username):
    user = User.objects.get(username=username)
    if user.user_type != User.EMPLOYER:
        # Redirect to the correct profile page if the user type is not employer
        return redirect('employee_profile', username=request.user.username)

    if request.method == 'POST':
        form = EmployerProfileForm(request.POST, instance=user.employerprofile)
        if form.is_valid():
            employer_profile = form.save(commit=False)
            employer_profile.user = user
            employer_profile.save()
            return redirect('employer_profile', username=request.user.username)
    else:
        form = EmployerProfileForm(instance=user.employerprofile)

    context = {
        'form': form,
        'username': username,
    }
    return render(request, 'employer_profile.html', context)

2. Employer Profile模型及关联代码

class EmployerProfile(models.Model):
   user = models.OneToOneField(User, on_delete=models.CASCADE)
   user_type = models.CharField(
        max_length=10,
        choices=User.USER_TYPE_CHOICES,
        default=User.EMPLOYER
    )
   first_name = models.CharField(max_length=255)
   last_name = models.CharField(max_length=255)
   title = models.CharField(max_length=255)
   company_name = models.CharField(max_length=255)
   company_logo = models.ImageField(upload_to='company_logos/')
   company_location = models.CharField(max_length=255)
   company_website = models.URLField()
   company_twitter = models.URLField()


#one-2-one connector
@receiver(post_save, sender=User)
def create_employer_profile(sender, instance, created, **kwargs):
   if created:
       EmployerProfile.objects.create(user=instance, user_type=instance.user_type)
       print('Employer Profile created')


@receiver(post_save, sender=User)
def save_employer_profile(sender, instance, **kwargs):
   instance.employerprofile.user_type = instance.user_type
   instance.employerprofile.save()
   print('Employer Profile saved')

3. User模型

#model one to store the user into db
class User(AbstractUser):
    EMPLOYER = "employer"
    EMPLOYEE = "employee"
    USER_TYPE_CHOICES = [
        (EMPLOYER, "Employer"),
        (EMPLOYEE, "Employee"),
    ]
    user_type = models.CharField(
        max_length=10,
        choices=USER_TYPE_CHOICES,
        default=EMPLOYEE
    )
    email = models.EmailField(default='example@example.com')
    username = models.CharField(max_length=150, default='example_user')
    password = models.CharField(max_length=128, default='!')
    groups = models.ManyToManyField(
        Group,
        blank=True,
        related_name='content_groups'
    )
    user_permissions = models.ManyToManyField(
        Permission,
        blank=True,
        related_name='content_user_permissions'
    )

已尝试的解决方法

  • 清空并重建数据库(因之前使用Django内置User模型,旧用户数据与新user_type字段不兼容)
  • 在雇主视图中添加默认雇主类型选项,并尝试从User模型获取用户类型

期望效果

Profile视图能与自定义User模型正常关联,允许用户添加额外的个人资料信息,且profile页面能获取到User类中初始存储的user_type属性。


解决方案

1. 配置自定义User模型到Django设置

如果settings.py未指定AUTH_USER_MODEL,Django会默认使用内置User模型,自然不存在user_type字段。在settings.py中添加:

AUTH_USER_MODEL = '你的应用名.User'

替换你的应用名为实际包含User模型的APP名称,比如accounts.User。

2. 修正视图中的User导入

确保视图中导入的是自定义User模型,而非Django内置模型:

# 错误写法
from django.contrib.auth.models import User

# 正确写法二选一
from 你的应用名.models import User
# 或推荐使用动态获取
from django.contrib.auth import get_user_model
User = get_user_model()

使用get_user_model()能避免硬编码,适配不同环境下的用户模型配置。

3. 重新生成并执行数据库迁移

即使重建过数据库,也需确保迁移文件正确生成并执行:

python manage.py makemigrations
python manage.py migrate

若之前有残留的无效迁移文件,可删除对应APP下migrations目录中除__init__.py外的所有文件,再重新执行上述命令。

4. 优化信号接收器逻辑(可选)

当前信号会给所有新建用户创建EmployerProfile,这不符合业务逻辑(仅雇主需要该Profile),调整后可避免后续异常:

@receiver(post_save, sender=User)
def create_employer_profile(sender, instance, created, **kwargs):
    if created and instance.user_type == User.EMPLOYER:
        EmployerProfile.objects.create(user=instance, user_type=instance.user_type)
        print('Employer Profile created')

5. 优化视图的用户获取逻辑(可选)

用get_object_or_404替代get,避免用户不存在时抛出500错误:

from django.shortcuts import get_object_or_404

def employer_profile_view(request, username):
    user = get_object_or_404(User, username=username)
    # 后续逻辑保持不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:25:30