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

