如何在Django中创建两种用户类型(普通用户与企业用户)
两种可复用Django默认User模型的企业账户实现方案
不用从零构建模型,下面两种方案既能复用User的所有字段(邮箱、密码、用户名等),还能轻松扩展企业专属字段:
方案一:OneToOneField关联默认User(适合已有项目,无需替换默认用户系统)
这种方案给每个企业账户绑定一个默认User实例,通过一对一关联扩展企业专属字段,完全复用User的核心功能。
1. 修正模型(models.py)
from django.contrib.auth.models import User class BusinessProfile(models.Model): # 一对一关联默认User,复用其所有字段 user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='business_profile') # 企业专属扩展字段 industry = models.CharField(max_length=100, blank=True, null=True, verbose_name="所属行业") credit_card_last4 = models.CharField(max_length=4, blank=True, null=True, verbose_name="信用卡后四位") # 禁止存储完整卡号 class Meta: verbose_name = "企业账户" verbose_name_plural = "企业账户" def __str__(self): return f"{self.user.email}(企业账户)"
2. 注册表单(forms.py)
同时处理User和企业扩展字段的表单:
from django import forms from django.contrib.auth.models import User from .models import BusinessProfile class BusinessRegisterForm(forms.Form): username = forms.CharField(max_length=150, label="用户名") email = forms.EmailField(label="邮箱") password = forms.CharField(widget=forms.PasswordInput, label="密码") industry = forms.CharField(max_length=100, required=False, label="所属行业") credit_card_last4 = forms.CharField(max_length=4, required=False, label="信用卡后四位") # 校验邮箱唯一性 def clean_email(self): email = self.cleaned_data.get('email') if User.objects.filter(email=email).exists(): raise forms.ValidationError("该邮箱已被注册") return email # 校验用户名唯一性 def clean_username(self): username = self.cleaned_data.get('username') if User.objects.filter(username=username).exists(): raise forms.ValidationError("该用户名已被占用") return username
3. 视图逻辑(views.py)
先创建User实例,再绑定企业扩展信息:
from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.models import User from .forms import BusinessRegisterForm from .models import BusinessProfile def business_registration(request): if request.method == 'POST': form = BusinessRegisterForm(request.POST) if form.is_valid(): # 提取表单数据 username = form.cleaned_data['username'] email = form.cleaned_data['email'] password = form.cleaned_data['password'] industry = form.cleaned_data['industry'] credit_card_last4 = form.cleaned_data['credit_card_last4'] # 创建默认User(自动加密密码) user = User.objects.create_user(username=username, email=email, password=password) # 创建企业扩展档案 BusinessProfile.objects.create(user=user, industry=industry, credit_card_last4=credit_card_last4) # 登录用户 user = authenticate(request, username=username, password=password) if user: login(request, user) return redirect('/') else: form = BusinessRegisterForm() return render(request, 'business_register.html', {'form': form})
方案二:自定义用户模型(AbstractUser,适合新项目)
直接继承Django的AbstractUser,把企业字段整合到用户模型里,无需额外关联,逻辑更简洁。
1. 自定义用户模型(models.py)
from django.contrib.auth.models import AbstractUser from django.db import models class CustomUser(AbstractUser): # 标记是否为企业账户 is_business = models.BooleanField(default=False, verbose_name="是否为企业账户") # 企业专属字段 industry = models.CharField(max_length=100, blank=True, null=True, verbose_name="所属行业") credit_card_last4 = models.CharField(max_length=4, blank=True, null=True, verbose_name="信用卡后四位") class Meta: verbose_name = "用户" verbose_name_plural = "用户"
2. 配置settings.py
告诉Django使用自定义用户模型:
AUTH_USER_MODEL = '你的APP名.CustomUser'
3. 注册表单(forms.py)
基于UserCreationForm扩展:
from django.contrib.auth.forms import UserCreationForm from .models import CustomUser class BusinessRegisterForm(UserCreationForm): industry = forms.CharField(max_length=100, required=False, label="所属行业") credit_card_last4 = forms.CharField(max_length=4, required=False, label="信用卡后四位") class Meta: model = CustomUser fields = ['username', 'email', 'password1', 'password2', 'industry', 'credit_card_last4'] def save(self, commit=True): user = super().save(commit=False) user.is_business = True # 标记为企业账户 if commit: user.save() return user
4. 视图逻辑(views.py)
简化版,直接保存表单即可:
from django.shortcuts import render, redirect from django.contrib.auth import login from .forms import BusinessRegisterForm def business_registration(request): if request.method == 'POST': form = BusinessRegisterForm(request.POST) if form.is_valid(): user = form.save() login(request, user) return redirect('/') else: form = BusinessRegisterForm() return render(request, 'business_register.html', {'form': form})
你现有代码的核心问题
你之前的BusinessModel用OneToOneField关联User的email和password是错误的——User本身已经包含这些字段,这种写法会导致一个企业账户关联两个不同的User实例,逻辑完全混乱。上面两种方案都能彻底解决这个问题,同时满足复用字段和后续扩展的需求。
内容的提问来源于stack exchange,提问作者Leonardo
相关产品推荐
相关产品推荐

